基于2个数据帧的Pandas高效数据操作

2024-10-08 21:24:27 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是我的代码和2个数据帧:

import pandas as pd
import numpy as np
df1 = pd.DataFrame(np.array([[1, 2, 3, 5, 2], [2, 2, 3, 5, 2], [3, 2, 3, 5, 2], [10, 2, 3, 5, 2]]),
                   columns=['ID', 'itemX_2', 'itemK_3', 'itemC_5', 'itemH_2'])
df2 = pd.DataFrame(np.array([[1,1,1, 2,2,2, 3,3,3, 10,10,10], [2,3,5, 2,3,5, 2,3,5, 2,3,5], [20,40,60, 80,100,200, 220,240,260, 500,505,520]]).T,
                   columns=['ID', 'Item_id', 'value_to_assign'])

基于df2,我想修改df1

预期产出:

df_expected_output = pd.DataFrame(np.array([[1, 20, 40, 60, 20], [2, 80, 100, 200, 80], [3, 220, 240, 260, 220], [10, 500, 505, 520, 500]]),
                   columns=['ID', 'itemX_2', 'itemK_3', 'itemC_5', 'itemH_2'])

我通过迭代列和一些操作来完成。在我的例子中,我在数据帧中得到了更多的列和行,所以速度非常慢。有人知道如何快速高效地完成吗?谢谢


Tags: columns数据importiddataframeasnparray
3条回答

另一种方法是:

  1. 堆叠要更换的原始df
  2. 抓取索引并拆分第二个索引以获取_之后的值
  3. 使用pd.Index.map,从df2映射这些索引的值
  4. 创建一个数据帧,将此映射值保留为值,将堆叠的多索引保留为索引,然后取消堆叠它们

s = df1.set_index("ID").stack()
i = s.index.map(lambda x: (x[0],x[1].split("_")[1]))
v = i.map(df2.set_index(["ID",df2['Item_id'].map(str)])['value_to_assign'])
out = pd.DataFrame({"value":v},index=s.index)['value'].unstack().reset_index()

print(out)

   ID  itemX_2  itemK_3  itemC_5  itemH_2
0   1       20       40       60       20
1   2       80      100      200       80
2   3      220      240      260      220
3  10      500      505      520      500

这里有一个解决方案pivotdf2具有类似于df1的格式,然后通过匹配最后一个“\u1”后面的数字逐列替换

df2_pivot = df2.pivot(index='ID', columns='Item_id', values='value_to_assign').rename_axis(None, axis=1)

df3 = df1.set_index('ID')
for c in df3:
    df3[c] = df2_pivot[int(c.rsplit('_', 1)[-1])]

或者,使用字典理解第二部分:

df3 = pd.DataFrame({c: df2_pivot[int(c.rsplit('_', 1)[-1])]
                    for c in df1.columns[1:]},
                    index=df1['ID']).reset_index()

输出:

>>> df3.reset_index()
   ID  itemX_2  itemK_3  itemC_5  itemH_2
0   1       20       40       60       20
1   2       80      100      200       80
2   3      220      240      260      220
3  10      500      505      520      500

^{}

我们可以使用pivot来重塑数据帧df2,这样我们就可以很容易地使用replace方法来替换df1中的值

df1.set_index('ID').T.replace(df2.pivot('Item_id', 'ID', 'value_to_assign')).T

    itemX_2  itemK_3  itemC_5  itemH_2
ID                                    
1        20       40       60       20
2        80      100      200       80
3       220      240      260      220
10      500      505      520      500

相关问题 更多 >

    热门问题