我有一个数据帧,我想在其中替换列中的值,但描述替换的dict基于另一列中的数值。示例数据帧如下所示:
Map me strings date
0 1 test1 2020-01-01
1 2 test2 2020-02-10
2 3 test3 2020-01-01
3 4 test2 2020-03-15
我有一本字典,看起来像这样:
map_dict = {'2020-01-01': {1: 4, 2: 3, 3: 1, 4: 2},
'2020-02-10': {1: 3, 2: 4, 3: 1, 4: 2},
'2020-03-15': {1: 3, 2: 2, 3: 1, 4: 4}}
我希望映射逻辑根据日期而有所不同。
在本例中,预期输出为:
Map me strings date
0 4 test1 2020-01-01
1 4 test2 2020-02-10
2 1 test3 2020-01-01
3 4 test2 2020-03-15
我有一个巨大的数据帧(100M+行(,所以如果可能的话,我真的想避免任何循环解决方案。
我试着想办法使用地图或替换,但没有成功
将DataFrame.join
与DataFrame
共导入器和DataFrame.stack
:创建的MultiIndex Series
一起使用
df = df.join(pd.DataFrame(map_dict).stack().rename('new'), on=['Map me','date'])
print (df)
Map me strings date new
0 1 test1 2020-01-01 4
1 2 test2 2020-02-10 4
2 3 test3 2020-01-01 1
3 4 test2 2020-03-15 4
也许试试这样的东西?
df['mapped'] = df.apply(lambda x: map_dict[x['date']][x['Map me']], axis=1)
尝试np.其中,它通常比pandas:性能更好
df["Mapped"] = ""
for key in map_dict.keys():
df["Mapped"] = np.where((df["date"] == key)&(df["Mapped"] == ""), df["Map me"].apply(lambda x: map_dict[key][x]), df["Mapped"])
结果:
Map me strings date Mapped
0 1 test1 2020-01-01 4
1 2 test2 2020-02-10 4
2 3 test3 2020-01-01 1
3 4 test2 2020-03-15 4
一种更像熊猫的方法是将map_dict
转换为DataFrame
,并将其连接到示例帧中。例如:
# Create the original dataframe
>>> df = pd.DataFrame([(1, 'test1', '2020-01-01'), (2, 'test2', '2020-02-10'), (3, 'test3', '2020-01-01'), (4, 'test2', '2020-03-15')], columns=['Map me', 'strings', 'date'])
>>> df
Map me strings date
0 1 test1 2020-01-01
1 2 test2 2020-02-10
2 3 test3 2020-01-01
3 4 test2 2020-03-15
# Convert the map dict to a dataframe
>>> map_df = pd.DataFrame([(k, j, l) for k, v in map_dict.items() for j,l in v.items()], columns=['date', 'Map me', 'Map to'])
>>> map_df
date Map me Map to
0 2020-01-01 1 4
1 2020-01-01 2 3
2 2020-01-01 3 1
3 2020-01-01 4 2
4 2020-02-10 1 3
5 2020-02-10 2 4
6 2020-02-10 3 1
7 2020-02-10 4 2
8 2020-03-15 1 3
9 2020-03-15 2 2
10 2020-03-15 3 1
11 2020-03-15 4 4
# Perform the join
>>> mapped_df = pd.merge(df, map_df, left_on=['date', 'Map me'], right_on=['date', 'Map me'])
>>> mapped_df
Map me strings date Map to
0 1 test1 2020-01-01 4
1 2 test2 2020-02-10 4
2 3 test3 2020-01-01 1
3 4 test2 2020-03-15 4
>>>