【问题标题】:Combining Pandas Dataframes结合 Pandas 数据框
【发布时间】:2021-03-20 16:08:25
【问题描述】:

我是 Pandas 的新手。所以请多多包涵。我有一个像这样的df

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

等等……

第 2 步

一旦我有了这 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

我该怎么办?

【问题讨论】:

  • 在手机上,所以无法测试。您可以使用 DF2.loc 中的每个列表来选择行。最终的组合可以用 pd.concat 来完成。
  • 您的数据不一致。请正确格式化。
  • @Vishnudev 有什么不一致的地方??无论如何,我收集你的想法,我认为我的格式很好。如果你想编辑,你可以
  • 你的数据中有.的点,是有意的吗?
  • @Vishnudev 不要刻薄,问题很明确。尽管 uniXVanXcel 您可以包含生成这些数据帧的代码。

标签: python pandas dataframe


【解决方案1】:

像这样使用单个数据框会更容易和更有效

初始化

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

【讨论】:

  • 这可能是最好的答案
【解决方案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]

-第二部分可以使用pd.concat:Documentation

-用于排序df.sort_valuesDocumentation

【讨论】:

  • 你不需要内部循环。只需使用 df.loc 中的列表
  • @AlexNe 如何在没有内部循环的情况下访问列表的各个元素?
  • 您可以使用 df.loc[s] 访问它们
【解决方案3】:
  1. 使用.loc.isin 获取新的Dataframe 以及df2 中的所需行
  2. 对这 4 个数据帧执行逻辑操作
  3. 使用pandas.concat() 组合生成的 4 个数据帧
  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')

【讨论】:

    【解决方案4】:

    首先,这段代码应该做你想做的事。

    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)]
    

    .

    split-apply-combine 上的 pandas 文档您可能也感兴趣:https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html

    【讨论】:

    • 感谢 lemme 理解并将其与我的情况相匹配并回复您。
    • 谢谢我最终使用了他的解决方案,因为它更具可读性,但感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2018-10-11
    • 2019-11-10
    • 2017-07-10
    • 2016-02-29
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    相关资源
    最近更新 更多