如何交叉检查 2 个熊猫数据帧文件并使用 1 个数据帧的值作为变量?



我有两个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,然后使用mergeleft来保持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

最新更新