【问题标题】:Python Pandas DataFrame Create Columns with specific value on iteration of every rowPython Pandas DataFrame 在每一行的迭代中创建具有特定值的列
【发布时间】:2021-04-26 08:09:23
【问题描述】:

假设我有一个pandas DataFrame,如下所示:

import pandas as pd
import numpy as np

df = pd.DataFrame({'ID':['B', 'A', 'A', 'C', 'A']})

#   ID
# 0  B
# 1  A
# 2  A
# 3  C
# 4  A

我有以下功能:

def func(id):
    # returns a list of three ['columnName', 'value'] pairs (values are random number between 0 and 5)
    # example: [[1,0], [3,4], [0,2]]
    res = [np.random.randint(0,5, size=2) for i in range(3)]
    return res

我想迭代ID 列中的每个值,对该值执行func(返回成对的['columnName', 'value']),然后对于func 返回的每一对值,我需要创建一个新列并将值分配给该特定行。这是一个示例输出:

  ID    1    3    0    2    4
0  B  3.0  4.0  NaN  3.0  NaN
1  A  0.0  4.0  4.0  NaN  4.0
2  A  1.0  1.0  1.0  0.0  NaN
3  C  1.0  1.0  NaN  NaN  NaN
4  A  1.0  4.0  0.0  2.0  0.0

为了澄清这一点,假设这个数组是由func 为第一行生成的:

[[1, 3], [3, 4], [2, 3]]

正如您在示例输出中看到的那样,名称为“1,3,2”的列分别创建为值“3,4,3”。

  ID    1    3    0    2    4
0  B  3.0  4.0  NaN  3.0  NaN

到目前为止我做了什么:

for id in df['ID']:
    for rowIndex in df.index[df['ID'] == id]:
        for columnName, value in func(id):
            df.loc[rowIndex, columnName] = value

这很好用! 唯一的问题是它根本没有效率。那是因为当我查找特定 ID 的 rowIndex(例如“A”)时,它可能会在列中多次出现并遍历它们。后来它也覆盖它们。没有更好的写法吗?

注意:

这只是我项目的简化版本。所以id 不被func 使用。此外,func 不会为特定的IDs 返回随机值,它会为每个ID 返回相同的值。

【问题讨论】:

    标签: python python-3.x pandas dataframe numpy


    【解决方案1】:

    第一个想法是与小组合作,但在DataFrame.join 之前必须由Series.unstack 重塑:

    df1 = df.join(df.groupby('ID')['ID'].apply(lambda x: dict(func(x))).unstack(), 'ID')
    

    为了提高性能,仅在 DataFrame.join 之前使用列表理解中的唯一值:

    u = df['ID'].unique()
    df1 = df.join(pd.DataFrame([dict(func(x)) for x in u], index=u), on='ID')
    print (df1)
    
      ID    4    0    3    1    2
    0  B  1.0  4.0  0.0  NaN  NaN
    1  A  2.0  NaN  NaN  1.0  NaN
    2  A  2.0  NaN  NaN  1.0  NaN
    3  C  NaN  2.0  1.0  NaN  0.0
    4  A  2.0  NaN  NaN  1.0  NaN
    

    【讨论】:

      【解决方案2】:

      你可以做series.map并创建一个数据框,然后加入

      df.join(pd.DataFrame(df['ID'].map(lambda x: dict(func(x))).tolist()))
      

      示例运行:

      np.random.seed(0)
      def func(id):
          # returns a list of three ['columnName', 'value'] pairs (values are random number between 0 and 5)
          # example: [[1,0], [3,4], [0,2]]
          res = [np.random.randint(0,5, size=2) for i in range(3)]
          return res
      print(df.join(pd.DataFrame(df['ID'].map(lambda x: dict(func(x))).tolist())))
      
        ID    4    3    0    2    1
      0  B  0.0  1.0  NaN  NaN  NaN
      1  A  0.0  2.0  4.0  NaN  NaN
      2  A  NaN  NaN  1.0  1.0  0.0
      3  C  NaN  0.0  NaN  NaN  4.0
      4  A  NaN  3.0  1.0  3.0  NaN
      

      【讨论】:

        猜你喜欢
        • 2017-10-08
        • 1970-01-01
        • 1970-01-01
        • 2020-05-27
        • 2022-11-20
        • 1970-01-01
        • 2018-08-03
        • 2023-03-21
        相关资源
        最近更新 更多