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]或该列表中的任何列 @ltaljukdf['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 DataFrame 列错误:传递的项目数错误 4,位置暗示 1