合并Pandas数据框架

3

我对Pandas比较陌生,请见谅。我有一个类似以下的数据框:

DF1
column1     column2(ids)   
a          [1,2,13,4,9]
b          [20,14,10,18,17]
c          [6,8,12,16,19]
d          [11,3,15,7,5]

每个列表中的数字对应于第二个数据帧中的列 ID。

DF2
id.  value_to_change. 
1      x1
2      x2
3      x3
4      x4
5      x5
6      x6
7      x7
8      x8
9      x9 
.      .
.      .
.      .
20    x20

步骤1

  1. 我想迭代每个列表,并选择DF2中具有匹配ID的行,同时创建4个数据框,因为在DF1中有4行。 如何做到这一点?

例如,对于应用逻辑后的第一行,我将得到以下结果

 id.    value_to_change
    1      x1
    2      x2
    13     x13
    14     x14
    9      x9

第二行将给我
  id.     value_to_change
    20      x20
    14      x14
    10      x10
    18      x18
    17      x17

接下来...

第二步

当我有了这4个数据框后,我将它们作为参数传递给一个逻辑函数,该函数会返回给我4个数据框。 2) 我应该如何将它们合并成一个排序后的最终数据框?

DF3
id.  new_value
1      y1
2      y2
3      y3
4      y4
5      y5
6      y6
7      y7
8      y8
9      y9 
.      .
.      .
.      .
20    y20

我该怎样处理这个问题?


1
在手机上,所以无法测试。您可以使用DF2.loc中的每个列表选择行。最后的组合可以使用pd.concat完成。 - AlexNe
您的数据不一致。请正确格式化。 - Vishnudev Krishnadas
@Vishnudev,它有什么不一致的地方吗??无论如何,我想你已经明白了我的意思,而且我认为我的格式没问题。如果您想编辑,可以这样做。 - uniXVanXcel
你的数据中有点号“.”,这是有意为之吗? - Vishnudev Krishnadas
1
@Vishnudev 不要太刻薄,问题很明确。虽然 uniXVanXcel,你可以包含生成这些数据框的代码。 - AlexNe
显示剩余2条评论
4个回答

3

使用单个数据框的方式会更加简便和高效,如下所示:

初始化

df1 = pd.DataFrame({'label': ['A', 'B', 'C', 'D'], 'ids': [[1,2,13,4,9], 
[20,14,10,18,17], [6,8,12,16,19],[11,3,15,7,5]]})

# Some custom function for dataframe operations
def my_func(x):
     x['value_to_change'] = x.value_to_change.str.replace('x', 'y') 
     return x

数据框操作

df1 = df1.explode('ids')
df1['value_to_change'] = df1.explode('ids')['ids'].map(dict(zip(df2.ids, df2.val)))
df1['new_value'] = df1.groupby('label').apply(my_func)['value_to_change']

输出

  label ids value_to_change new_value
0     A   1              x1        y1
0     A   2              x2        y2
0     A  13             x13       y13
0     A   4              x4        y4
0     A   9              x9        y9
1     B  20             x20       y20
1     B  14             x14       y14
1     B  10             x10       y10
1     B  18             x18       y18
1     B  17             x17       y17
2     C   6              x6        y6
2     C   8              x8        y8
2     C  12             x12       y12
2     C  16             x16       y16
2     C  19             x19       y19
3     D  11             x11       y11
3     D   3              x3        y3
3     D  15             x15       y15
3     D   7              x7        y7
3     D   5              x5        y5

1
这可能是最好的答案。 - AlexNe

2
这段代码将帮助解决问题的第一部分。
import pandas as pd
df1 = pd.DataFrame([[[1,2,4,5]],[[3,4,1]]], columns=["column2(ids)"])
df2 = pd.DataFrame([[1,"x1"],[2,"x2"],[3,"x3"],[4,"x4"],[5,"x5"]], columns=["id", "value_to_change"])
df3 = pd.DataFrame(columns=["id", "value_to_change"])
for row in df1.iterrows():
    s = row[1][0]
    for item in s:
        val = df2.loc[df2['id']==item, 'value_to_change'].item()
        df_temp = pd.DataFrame([[item,val]], columns=["id", "value_to_change"])
        df3 = df3.append(df_temp, ignore_index=True)
df3

在代码行 s=row[1][0] 中,你需要根据你的数据框选择正确的索引。在我的情况下,它是 [1][0]

Output

-第二部分可以使用pd.concat文档 -对于排序,使用df.sort_values文档

你不需要内部循环。只需在df.loc中使用列表即可。 - AlexNe
@AlexNe 如何在没有内部循环的情况下访问列表中的单个元素? - Cute Panda
你可以使用 df.loc[s] 访问它们。 - AlexNe

1

首先,这段代码应该能够实现你的需求。

import pandas as pd

idxs = [
    [0,2],
    [1,3],
]

df_idxs = pd.DataFrame({'idxs': idxs})

df = pd.DataFrame(
    {'data': ['a', 'b', 'c', 'd']}
)

frames = []
for _, idx in df_idxs.iterrows():
    rows = idx['idxs']
    frame = df.loc[rows]
    # some logic
    print(frame)
    #collect
    frames.append(frame)
    
pd.concat(frames)

请注意,如果没有传递任何参数,pandas会自动创建一个范围索引。如果您想选择不同的列,请将其设置为索引,或使用其他方法。
df.loc[df.data.isin(rows)]

.

如果您对分割-应用-合并有兴趣,您可能会对Pandas文档感兴趣:https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html


谢谢,让我理解并将其与我的情况匹配,然后再回复您。 - uniXVanXcel
谢谢你的帮助,最终我使用了他的解决方案,因为它更易读。但还是感谢你的帮助。 - uniXVanXcel

1
  1. 使用 .loc.isin 获取在 df2 中所需行的新的 Dataframe
  2. 对这 4 个数据框进行逻辑操作
  3. 使用 pandas.concat() 合并结果为一个数据框
  4. 使用 .sort_values() 按照 id 对数据框进行排序

代码:

import pandas as pd

df1 = pd.DataFrame({'column1     ': ['A', 'B', 'C', 'D'], 'ids': [[1,2,13,4,9], [20,14,10,18,17], [6,8,12,16,19],[11,3,15,7,5]]})
df2 = pd.DataFrame({'ids': list(range(1,21)), 'val': [f'x{x}' for x in range(1,21)]})

df_list=[]
for id_list in df1['ids'].values:
    df_list.append(df2.loc[df2['ids'].isin(id_list)])

# do logic on each DF in df_list

# assuming df_list now contains the resulting dataframes
df3 = pd.concat(df_list)
df3 = df3.sort_values('ids')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接