Pandas 重新索引并将列分配给新列

Posted

技术标签:

【中文标题】Pandas 重新索引并将列分配给新列【英文标题】:Pandas reindex and assigning Columns to a new column 【发布时间】:2021-04-11 18:21:29 【问题描述】:

我正在创建一个 pandas 数据框,并希望通过分配和重新索引方法来创建一个新列。我正在做的方式是提取可能有“A”、“B”、“C”、“D”、“E”列的数据 我想创建一个新列,比如“XX”。 (当然,数据框中还有其他列,而且它很大,我只在下面展示这个示例)。 XX 列通常是 A->E 列的 OR 逻辑或最大值

喜欢

输入:

     df 
             A   B   C    D   E  
             0   0   1    0   1
             0   0   0    0   0
             1   0   0    0   0

输出:

    df
             A   B   C    D   E     XX 
             0   0   1    0   1     1
             0   0   0    0   0     1
             1   0   0    0   0     1

所以我的做法

    ICOLS  = ["A", "B", "C", "D", "E]

    df = (df.assign(XX=df.reindex(ICOLS, axis=1).dropna().max(axis=1)).dropna(axis=1, how='all'))

脚本工作正常,但只有当我拥有从 A 到 E 的所有列时它才工作。在数据库中很多次(比如缺少 C 或 E 等),但我仍然希望具有相同的逻辑和 XX应该给出类似的输出。

所以如果数据库只有 A、B 和 E 行,那么:

输入:

     df 
             A   B   E  
             0   0   1
             0   0   0
             1   0   0

输出:

    df
             A   B   E     XX 
             0   0   1     1
             0   0   0     1
             1   0   0     1

我不确定如何以我在 inputCols ICOLS 列表中的方式实现这一点。如果对我试图解决的方向有帮助,我将不胜感激。任何帮助将不胜感激。谢谢

【问题讨论】:

xx 的预期输出是否正确?根据描述和示例代码,我认为每个输出的第二行应该是0 【参考方案1】:

您可以创建列的基本列表,然后检查这些列是否存在于您的 df 中:

BASE_COLUMNS  = ["A", "B", "C", "D", "E"]
available_cols = [column for column in df.columns if column in BASE_COLUMNS]

最后,应用您的解决方案,但现在将 available_cols 作为列传递:

df = (df.assign(XX=df.reindex(available_cols, axis=1).dropna().max(axis=1)).dropna(axis=1, how='all'))

这将处理缺少某些列的情况

【讨论】:

绝对是的!谢谢。已接受解决方案!【参考方案2】:

一行完成。

请过滤所需的列。将您需要的列放在一个列表中。这将过滤它们,尝试在每一行中找到最大值到一个新列中,然后在结果列中找到最大值

数据

 print(df)

   A  B  C   f  D  E
0  0  0  1   2  0  1
1  0  0  0  56  0  0
2  1  0  0  70  0  0

解决方案;

df['xx']=df.filter(items=['A', 'B','E','D']).max(1).max(0)

ICOLS  = ["A", "B", "C", "D", "E"]
df['xx']=df.filter(items=ICOLS).max(1).max(0)

打印(df)

   A  B  C   f  D  E  xx
0  0  0  1   2  0  1   1
1  0  0  0  56  0  0   1
2  1  0  0  70  0  0   1

【讨论】:

我不明白你的解决方案。基本问题是很多时候所有五列都不存在,所以我仍然需要具有相同逻辑的 XX 输出。当我拥有 A&E 的所有列时,我的代码就可以工作了。但是每当我缺少一列(比如 C 等)时,代码就会失败。 这不会解决他的问题,因为他有几个列,并且他只想将他的解决方案应用于 ["A", "B", "C", "D", "E]或该列表中的任何列 @ltaljuk df['xx']=df.filter(items=['A', 'B','E','D']).max(1).max(0) 是的,这将解决问题,但是...当 A、B、C、D 或 E 丢失时会发生什么???【参考方案3】:

注意:按照@wwnde 的建议使用filter 可能会更好

如果您的主要问题是根据可用列选择列,您可以简单地查看df.columns 以获取可用列。

>>> df = pd.DataFrame(
...     [
...         [0, 0, 1, 0, 1],
...         [0, 0, 0, 0, 0],
...         [1, 0, 0, 0, 0]
...     ],
...     columns=['A', 'B', 'C', 'D', 'E']
... )
>>> df
   A  B  C  D  E
0  0  0  1  0  1
1  0  0  0  0  0
2  1  0  0  0  0

>>> df.columns
Index(['A', 'B', 'C', 'D', 'E'], dtype='object')

然后使用 Python set 你可以找到交叉点。

>>> ICOLS  = ["A", "B", "C", "D", "E"]
>>> set(df.columns) & set(ICOLS)
'D', 'B', 'C', 'E', 'A'

合起来可能是:

>>> df.assign(XX=df[set(df.columns) & set(ICOLS)].max(1))
   A  B  C  D  E  XX
0  0  0  1  0  1   1
1  0  0  0  0  0   0
2  1  0  0  0  0   1

【讨论】:

这行得通,但比我前进的方向要多一点。谢谢。这是另一种解决方案!

以上是关于Pandas 重新索引并将列分配给新列的主要内容,如果未能解决你的问题,请参考以下文章

在pandas中,我可以同时映射列并将列插入特定索引吗?

过滤 Pandas DataFrame 列错误:传递的项目数错误 4,位置暗示 1

拆分熊猫列并将最后一个元素添加到新列

根据两个 pandas DataFrames 之间的条件为新列分配值

pandas基础运算

Python-Pandas。根据列表中列的存在重新分配列的值