首页 > 解决方案 > 根据熊猫中的条件填充数据框列

问题描述

我有两个数据框,如下所示

         df_input                                    df_output
id       POLL_X  POLL_Y  POLL_Z ..     id   Pass_01  Pass_02  Pass_03 .....
110101       1       2       4       110101             
110102       2       1       3       110102

并且要求是根据 df_input 中的值填写 df_ouput

            df_input                                    df_output
  id   POLL_X  POLL_Y  POLL_Z ....       id   Pass_01  Pass_02  Pass_03 .....
110101     1       2       3            110101     X       Y         Z  
110102     2       1       3            110102     Y       X         Z

所以基本上来自 df_input 的列值将是 df_output 中的单元格值,而匹配并基于 df_input.id == df_output.id

我正在尝试如下

def function1(df_input, number):
       dfwithCols = df_input[df_input.columns[pd.Series(df_input.columns).str.startswith('POLL_')]]
       list_cols = dfwithCols .columns[(dfwithCols == float(number)).iloc[0]]
       colValue = (dfReduced == float(index)).idxmax(axis=1)[0]
       return colValue

--驱动功能--

for i in range(1,number_of_columnswithPass):
      df_output['Pass_'+i] = function1(df_input,i)

number_of_columnsiwthPass 是常量,它给出名称为 pass 的总列数。

此外,我不能遍历每一行,因为这将花费大量时间,必须在基于列或基于 lambda 的情况下进行

两个数据框中还有其他列,也必须匹配 df_input.id == df_output.id

列的总数可以在 40 左右,一些测试值包括 POLL_DNW 、 POLL_DO、 POLL_DOES 、 POLL_SIG:2
所以我必须取 '_' 之后的任何内容以及 01,02,03,04 之类的列号- --10,11,--21,---39,40

标签: pythonpython-3.xpandaspython-2.7dataframe

解决方案


我假设一开始你的df_output有正确的列名(因为它们应该在填充之后)。

完成你的任务:

  1. import re(稍后会用到)。

  2. 根据源行定义以下生成输出行的函数:

    def genRow(row):
        ind = []
        vals = []
        for k, v in row.iteritems():
            mtch = re.match('POLL_(.+)', k)
            if mtch:
                ind.append('Pass_' + str(v).zfill(2))
                vals.append(mtch.group(1))
            else:
                ind.append(k)
                vals.append(v)
        return pd.Series(vals, index=ind).rename(row.name)
    

    请注意,此函数用相应的Pass_...列“替换”任何POLL_...列,并使其他列保持原样。

  3. 应用它:

    df_output = df_input.apply(genRow, axis=1).reindex(columns=df_output.columns)
    

脚步:

  • df_input.apply(...)- 生成“初步”输出 DataFrame。请注意,现在列顺序是按字母顺序排列的。
  • reindex(...)- 使用 df_output 中的列名重新索引上述 DataFrame 提供正确的列顺序。
  • df_output =-用上述结果覆盖df_output 。

编辑

如果您的输入 DataFrame 在POLL_...列中包含重复值,则需要稍作修改。这种情况会导致这两个(或更多)元素具有 相同索引的输出行,因此如果包含这样的行,则无法构造整个 DataFrame。

补救措施是将这些元素“压缩”成一个具有原始索引的元素,并将所有值转换为字符串,例如包含逗号分隔的原始值列表。

为此,请将 genRow函数中的最后一行更改为:

out = pd.Series(vals, index=ind).rename(row.name)
return out.groupby(lambda key: key).apply(lambda lst: (', '.join(sorted(lst))))

推荐阅读