复杂的列表列到列字符串匹配和派生另一列
complicated list column to column string matching and deriving another column
数据帧:
df1:
ind_lst
[agriculture_dairy, analytics]
[architecture_planning, advertising_pr_events, analytics]
df2:
ind score
advertising_pr_events 3.672947168
agriculture_dairy 3.368266582
airlines_aviation_aerospace 3.60798955
analytics 3.67752552
architecture_planning 3.853236675
我有2个数据框,如上所示。
df2 的 ind 列是字符串类型并且具有行业名称。 df2.score 每个行业都有一个独特的分数。
df1的ind_lst列是df2.ind
的独特元素的不同组合形成的行业名称列表
我想在 df1 avg_score 中创建一个列,最终输出如下:
avg_score 在 df1 的第 1 行是来自 df2 的分数的平均值对应于 agriculture_dairy,analytics
df1 的第 2 行中的 avg_score 是来自 df2 的分数的平均值,对应于 architecture_planning、advertising_pr_events、分析。
df1
ind_lst avg_score
[agriculture_dairy, analytics] 3.522896051
[architecture_planning, advertising_pr_events, analytics] 3.734569787666667
如何在python中实现这个?
我试过这个:
avg=[]
avgs=[]
for i in df1.ind_lst:
for j in i:
a= df2[df2['ind'] == j].index
avg.append(df2.loc[a]['score'])
avgs.append(mean(avg))
df1['avg_score']= avgs
代码运行不正常。我得到一个空列表作为输出。
注意:我已经对数据帧进行了采样并仅共享了问题陈述的一部分。真实的数据帧 df1 有 90k 个条目 & df2 有 860 行。
选项 1:根据 df2 创建 ind 和 score 地图。使用列表理解将分数映射到行业并计算平均值。
mapper = df2.set_index('ind')['score'].to_dict()
df1['avg_score'] = df1['ind_lst'].apply(lambda x: np.mean([mapper[i] for i in x]))
ind_lst avg_score
0 [agriculture_dairy, analytics] 3.522896
1 [architecture_planning, advertising_pr_events,... 3.734570
选项 2:使用 DataFrame.explode 取消嵌套列表,groupby 索引并应用 mean
df1['avg_score'] = df1['ind_lst'].explode().map(mapper).groupby(level = 0).mean()
您可以像这样使用列表作为 df2 的索引,而不是像 那样使用映射器和列表理解。
df1["average_score"] = df1["ind_lst"].apply(lambda lst: df2.loc[lst, "score"].mean())
数据帧:
df1:
ind_lst
[agriculture_dairy, analytics]
[architecture_planning, advertising_pr_events, analytics]
df2:
ind score
advertising_pr_events 3.672947168
agriculture_dairy 3.368266582
airlines_aviation_aerospace 3.60798955
analytics 3.67752552
architecture_planning 3.853236675
我有2个数据框,如上所示。
df2 的 ind 列是字符串类型并且具有行业名称。 df2.score 每个行业都有一个独特的分数。
df1的ind_lst列是df2.ind
的独特元素的不同组合形成的行业名称列表我想在 df1 avg_score 中创建一个列,最终输出如下:
avg_score 在 df1 的第 1 行是来自 df2 的分数的平均值对应于 agriculture_dairy,analytics
df1 的第 2 行中的avg_score 是来自 df2 的分数的平均值,对应于 architecture_planning、advertising_pr_events、分析。
df1
ind_lst avg_score
[agriculture_dairy, analytics] 3.522896051
[architecture_planning, advertising_pr_events, analytics] 3.734569787666667
如何在python中实现这个? 我试过这个:
avg=[]
avgs=[]
for i in df1.ind_lst:
for j in i:
a= df2[df2['ind'] == j].index
avg.append(df2.loc[a]['score'])
avgs.append(mean(avg))
df1['avg_score']= avgs
代码运行不正常。我得到一个空列表作为输出。
注意:我已经对数据帧进行了采样并仅共享了问题陈述的一部分。真实的数据帧 df1 有 90k 个条目 & df2 有 860 行。
选项 1:根据 df2 创建 ind 和 score 地图。使用列表理解将分数映射到行业并计算平均值。
mapper = df2.set_index('ind')['score'].to_dict()
df1['avg_score'] = df1['ind_lst'].apply(lambda x: np.mean([mapper[i] for i in x]))
ind_lst avg_score
0 [agriculture_dairy, analytics] 3.522896
1 [architecture_planning, advertising_pr_events,... 3.734570
选项 2:使用 DataFrame.explode 取消嵌套列表,groupby 索引并应用 mean
df1['avg_score'] = df1['ind_lst'].explode().map(mapper).groupby(level = 0).mean()
您可以像这样使用列表作为 df2 的索引,而不是像
df1["average_score"] = df1["ind_lst"].apply(lambda lst: df2.loc[lst, "score"].mean())