匹配两个数据框列,return 不同的列值
match two dataframe columns, return different column value
这个应该很简单,但是好像找不到。
dfA # 学生姓名列表(我的列表中有 500 名学生)- 简称为名字
ID
Cola
00
None
01
Mike
02
Sue
03
Tom
dfB # UID 是 class 科目(在另一个 df 中)(34 个独立的 class 科目)(通常每个 class 有 20 名学生)
UID
ID1
ID2
ID3
01
01
02
03
02
02
03
00
预期输出
dfB
UID
ID1
ID2
ID3
01
Mike
Sue
Tom
02
Sue
Tom
None
我对 python 中的 Dataframe 操作真的很陌生。
我查看了地图、掩码、查询,但似乎没有什么合适的,
因为 header 个不同的名字。
有人请求实际代码,这就是我得到的:
...
dcol1 = [14, 12, 18, 28, 107, 303, 421]
dcol2 = [15, 12, 17, 29, 108, 305, 421]
colh = ['UID', 'id1', 'id2', 'id3', 'id4', 'id5', 'id6']
dfA = pd.DataFrame(columns=list(colh))
dfA.loc[0] = dcol1
dfA.loc[1] = dcol2
print(dfA)
ncol1 = [12, 17, 18, 29, 107, 108, 303, 305, 421]
ncol2 = ["Mike", "Tom", "Sue", "Carol", "John", "Sam", "Tim", "Linda", "Jim"]
dfB = pd.DataFrame({'NID':ncol1, 'Name':ncol2})
print(dfB)
# replace number ids with names
dfB = dfB.applymap(lambda i: dfA.iloc[i]['Name'])
print(dfB)
...
如您所见,我确实从基础上简化了它。
编辑
根据评论交流
我更新了提供的代码(与上面的示例相比,您颠倒了 dfA 和 dfB,dfA 中缺少 NID 28,我将正确的列设置为索引),它现在对我来说工作正常。
import pandas as pd
ncol1 = [12, 17, 18, 28, 29, 107, 108, 303, 305, 421]
ncol2 = ["Mike", "Tom", "Sue", "ADDED 28", "Carol", "John", "Sam", "Tim", "Linda", "Jim"]
dfA = pd.DataFrame({'NID':ncol1, 'Name':ncol2})
dfA = dfA.set_index('NID')
print('dfA', dfA)
dcol1 = [14, 12, 18, 28, 107, 303, 421]
dcol2 = [15, 12, 17, 29, 108, 305, 421]
colh = ['UID', 'id1', 'id2', 'id3', 'id4', 'id5', 'id6']
dfB = pd.DataFrame(columns=list(colh))
dfB.loc[0] = dcol1
dfB.loc[1] = dcol2
dfB = dfB.set_index('UID')
print('Intial dfB', dfB)
# replace number ids with names
dfB = dfB.applymap(lambda i: dfA.loc[i]['Name'])
print('Final dfB', dfB)
初步解决方案
当dfB中有很多列时就不那么自然了。
没有问题中的格式就没那么容易了,但你有没有尝试过类似
的方法
dfB.join(dfA, on='ID1', rsuffix='1') \
.join(dfA, on='ID2', rsuffix='2') \
.join(dfA, on='ID3', rsuffix='3')
然后从最终数据框中保留您需要的列(在您的情况下为 COLA1, COLA2, COLA3
)。
这个应该很简单,但是好像找不到。
dfA # 学生姓名列表(我的列表中有 500 名学生)- 简称为名字
ID | Cola |
---|---|
00 | None |
01 | Mike |
02 | Sue |
03 | Tom |
dfB # UID 是 class 科目(在另一个 df 中)(34 个独立的 class 科目)(通常每个 class 有 20 名学生)
UID | ID1 | ID2 | ID3 |
---|---|---|---|
01 | 01 | 02 | 03 |
02 | 02 | 03 | 00 |
预期输出
dfB
UID | ID1 | ID2 | ID3 |
---|---|---|---|
01 | Mike | Sue | Tom |
02 | Sue | Tom | None |
我对 python 中的 Dataframe 操作真的很陌生。 我查看了地图、掩码、查询,但似乎没有什么合适的, 因为 header 个不同的名字。
有人请求实际代码,这就是我得到的:
...
dcol1 = [14, 12, 18, 28, 107, 303, 421]
dcol2 = [15, 12, 17, 29, 108, 305, 421]
colh = ['UID', 'id1', 'id2', 'id3', 'id4', 'id5', 'id6']
dfA = pd.DataFrame(columns=list(colh))
dfA.loc[0] = dcol1
dfA.loc[1] = dcol2
print(dfA)
ncol1 = [12, 17, 18, 29, 107, 108, 303, 305, 421]
ncol2 = ["Mike", "Tom", "Sue", "Carol", "John", "Sam", "Tim", "Linda", "Jim"]
dfB = pd.DataFrame({'NID':ncol1, 'Name':ncol2})
print(dfB)
# replace number ids with names
dfB = dfB.applymap(lambda i: dfA.iloc[i]['Name'])
print(dfB)
...
如您所见,我确实从基础上简化了它。
编辑
根据评论交流
我更新了提供的代码(与上面的示例相比,您颠倒了 dfA 和 dfB,dfA 中缺少 NID 28,我将正确的列设置为索引),它现在对我来说工作正常。
import pandas as pd
ncol1 = [12, 17, 18, 28, 29, 107, 108, 303, 305, 421]
ncol2 = ["Mike", "Tom", "Sue", "ADDED 28", "Carol", "John", "Sam", "Tim", "Linda", "Jim"]
dfA = pd.DataFrame({'NID':ncol1, 'Name':ncol2})
dfA = dfA.set_index('NID')
print('dfA', dfA)
dcol1 = [14, 12, 18, 28, 107, 303, 421]
dcol2 = [15, 12, 17, 29, 108, 305, 421]
colh = ['UID', 'id1', 'id2', 'id3', 'id4', 'id5', 'id6']
dfB = pd.DataFrame(columns=list(colh))
dfB.loc[0] = dcol1
dfB.loc[1] = dcol2
dfB = dfB.set_index('UID')
print('Intial dfB', dfB)
# replace number ids with names
dfB = dfB.applymap(lambda i: dfA.loc[i]['Name'])
print('Final dfB', dfB)
初步解决方案
当dfB中有很多列时就不那么自然了。
没有问题中的格式就没那么容易了,但你有没有尝试过类似
的方法dfB.join(dfA, on='ID1', rsuffix='1') \
.join(dfA, on='ID2', rsuffix='2') \
.join(dfA, on='ID3', rsuffix='3')
然后从最终数据框中保留您需要的列(在您的情况下为 COLA1, COLA2, COLA3
)。