我有两个Panda数据帧:
模式2:
Mode month1 month2 month3 month4 month5 month6 month7 month8 month9 month10 month11 month12
0 100 0 0 0 0 0 0 0 0 0 0 0 0
2 602 0 2 1 0 2 1 0 2 1 0 2 1
3 603 1 0 2 1 0 2 1 0 2 1 0 2
11 802 0 11 10 9 8 7 6 5 4 3 2 1
df_ia:
RevalMonth_plus Mode
0 1 602
35 1 100
52 4 100
79 1 802
94 4 603
95 4 603
96 4 603
98 1 100
逻辑是将dfia的每行与modal2的每行进行比较,如果dfia的行与modala2的行具有相同的Mode编号,则将modala2列month1添加到dfia。
我可以通过以下代码成功完成这一部分:
for index, row in modal2.iterrows():
conditions.append(df_ia['Mode'] == row['Mode'])
for col in ['month1']: #for loop list is because sometime need more than 1 column
col_v = modal2[col]
df_ia[col] = np.select(conditions, col_v, default=None)
输出为:
RevalMonth_plus Mode month1
0 1 602 0
35 1 100 0
52 4 100 0
79 1 802 0
94 4 603 1
95 4 603 1
96 4 603 1
98 1 100 0
但挑战在于:
如何将"month1"替换为df_ia中相应的"RevalMonth_plus",如下所示:
for col in [f'month{df_ia['RevalMonth_plus']}']: #for loop list is because sometime need more than 1 column
col_v = modal2[col]
df_ia[col] = np.select(conditions, col_v, default=None)
理想的输出应该是:
RevalMonth_plus Mode dynamic_moth_value
0 1 602 0 #month1
35 1 100 0 #month1
52 4 100 0 #month4
79 1 802 0 #month1
94 4 603 1 #month4
95 4 603 1 #month4
96 4 603 1 #month4
98 1 100 0 #month1
我已经花了一整天的时间在上面了。但是我做不到。
另一个解决方案:
x = pd.merge(df_ia, modal2, on="Mode", how="left")
x["dynamic_month_value"] = x.apply(
lambda x: x["month" + str(x["RevalMonth_plus"])], axis=1
)
print(x[["RevalMonth_plus", "Mode", "dynamic_month_value"]])
打印:
RevalMonth_plus Mode dynamic_month_value
0 1 602 0
1 1 100 0
2 4 100 0
3 1 802 0
4 4 603 1
5 4 603 1
6 4 603 1
7 1 100 0
尝试使用pd.wide_to_long
来重塑数据帧modal2
,然后使用merge
left
来保持df_ia
:的顺序
df_long = pd.wide_to_long(modal2, stubnames='month',
i='Mode', j='RevalMonth_plus').reset_index()
new_df = df_ia.merge(
df_long,
how='left',
on=['RevalMonth_plus', 'Mode']
).rename(columns={'month': 'dynamic_month_value'})
new_df
:
RevalMonth_plus Mode dynamic_month_value
0 1 602 0
1 1 100 0
2 4 100 0
3 1 802 0
4 4 603 1
5 4 603 1
6 4 603 1
7 1 100 0
具有唯一值以更清楚地显示映射的示例:
modal2 = pd.DataFrame({
'Mode': [100, 602, 603, 802],
'month1': [1, 2, 3, 4],
'month4': [5, 6, 7, 8]
})
df_ia = pd.DataFrame({
'RevalMonth_plus': [1, 1, 4, 1, 4, 4, 4, 1],
'Mode': [602, 100, 100, 802, 603, 603, 603, 100]
})
modal2
:
Mode month1 month4
0 100 1 5
1 602 2 6
2 603 3 7
3 802 4 8
df_ia
:
RevalMonth_plus Mode
0 1 602
1 1 100
2 4 100
3 1 802
4 4 603
5 4 603
6 4 603
7 1 100
new_df
:
RevalMonth_plus Mode dynamic_month_value
0 1 602 2
1 1 100 1
2 4 100 5
3 1 802 4
4 4 603 7
5 4 603 7
6 4 603 7
7 1 100 1
所有月份的列都可以首先使用merge
进行映射:
# Merge left to bring all Month columns into new_df
new_df = df_ia.merge(modal2, on='Mode', how='left')
df_long = pd.wide_to_long(modal2, stubnames='month',
i='Mode', j='RevalMonth_plus').reset_index()
new_df = new_df.merge(
df_long,
how='left',
on=['RevalMonth_plus', 'Mode']
).rename(columns={'month': 'dynamic_month_value'})
RevalMonth_plus Mode month1 month4 dynamic_month_value
0 1 602 2 6 2
1 1 100 1 5 1
2 4 100 1 5 5
3 1 802 4 8 4
4 4 603 3 7 7
5 4 603 3 7 7
6 4 603 3 7 7
7 1 100 1 5 1
对数据帧行进行迭代几乎总是错误的。您需要合并数据帧:
df_ia['dynamic_month_value'] = modal2.merge(df_ia).set_index(df_ia.index)['month1']
# RevalMonth_plus Mode dynamic_month_value
#0 1 602 0
#35 1 100 0
#52 4 100 0
#79 1 802 0
#94 4 603 1
#95 4 603 1
#96 4 603 1
#98 1 100 0