如何将 Pandas 数据帧中的多列弹出到新数据帧中?

How do you pop multiple columns off a Pandas dataframe, into a new dataframe?

提问人:Sean McCarthy 提问时间:3/17/2018 更新时间:3/30/2022 访问量:29429

问:

假设我有以下几点:

df = pd.DataFrame({'a':range(2), 'b':range(2), 'c':range(2), 'd':range(2)})

我想将数据帧中的两列(“c”和“d”)“弹出”到一个新的数据帧中,将“a”和“b”留在原始 df 中。以下方法不起作用:

df2 = df.pop(['c', 'd'])

这是我的错误:

TypeError: '['c', 'd']' is an invalid key

除了执行以下操作外,还有谁知道一个快速、优雅的解决方案?

df2 = df[['c', 'd']]
df3 = df[['a', 'b']]

我知道上面的代码输入起来并不那么乏味,但这就是发明 DataFrame.pop 的原因——在从数据库中弹出一列时为我们节省了一个步骤。

蟒蛇 熊猫

评论

0赞 ChootsMagoots 3/17/2018
我不知道这是否有效,但你试过了吗?df.pop([['c', 'd']])
1赞 ALollz 3/17/2018
pop 返回一个 Series,因此您只能返回一列。pop
0赞 Sean McCarthy 3/17/2018
@ChootsMagoots,如果我尝试您的建议,它会说 TypeError: unhashable type: 'list'
1赞 pault 3/17/2018
你可以做类似的事情,但我不知道这是否比你的不优雅的解决方案更容易。pd.DataFrame([df.pop(x) for x in ['c', 'd']]).T

答:

39赞 cs95 3/17/2018 #1

这必须是一个两步过程(您无法绕过这个问题,因为正如正确提到的,适用于单个列并返回一个 Series)。pop

首先,切片(步骤 1),然后删除这些列(步骤 2)。df

df2 = df[['c', 'd']].copy()
df = df.drop(['c', 'd'], axis=1)

这是单行版本,使用:pd.concat

df2 = pd.concat([df.pop(x) for x in ['c', 'd']], axis=1)

这仍然是一个两步过程,但你是在一行内完成的。

df

   a  b
0  0  0
1  1  1

df2

   c  d
0  0  0
1  1  1

话虽如此,我认为允许采用类似列表的列标题适当地返回弹出列的 DataFrame 是有价值的。这将对 GitHub 提出一个很好的功能请求,假设有时间编写一个。pop

评论

1赞 la_leche 2/14/2019
定义 df 然后运行命令 df2 = df[['c', 'd']].copy() 返回错误 '['c', 'd']' is an invalid key。这个答案是过时了还是我遗漏了什么?
0赞 cs95 2/14/2019
你@la_leche错误地做了df['c', 'd']?或者,也许您不小心传递了一个字符串而不是一个列表?
1赞 kawingkelvin 6/27/2020
如果您知道 2 行与 1 行方法之间的内存占用差异,您能否发表评论。我认为单行 IMO 更优雅(不丑陋)。如果列数的 # 较大,则 2 行可能会导致更多的人为错别字。
0赞 cs95 10/1/2021
再看一遍,更有可能的是,一个衬垫更可取,因为工作地点是有效的,而不是在每个停靠点创建多个副本的 2 个衬垫方法。虽然没有基准测试。pop
0赞 Collin Cunningham 6/2/2023
我认为单行版本实际上有点危险。如果在中途遇到关键错误,则会留下一个缺少某些列的帧,但并非所有列都取决于错误发生的位置
7赞 pault 3/17/2018 #2

这是一个替代方案,但我不确定它是否比您的原始解决方案更优雅:

df2 = pd.DataFrame([df.pop(x) for x in ['c', 'd']]).T
df3 = pd.DataFrame([df.pop(x) for x in ['a', 'b']]).T

输出:

print(df2)
#   c  d
#0  0  0
#1  1  1

print(df3)
#   a  b
#0  0  0
#1  1  1

评论

3赞 cs95 3/17/2018
你可以通过使用来绕过不必要的转调。但是 +1pd.concat
0赞 pault 3/17/2018
啊,我明白了——这就是我所缺少的。axis=1
0赞 darrahts 9/29/2021
我认为这个解决方案值得更多的赞成,但不确定为什么复制和粘贴接受答案的网站称其为“丑陋”。OP 询问了关于弹出多个列的问题,这个答案清楚地表明了这就是正在发生的事情,并且在一行中完成,而不管在幕后实际执行的步骤数如何(毕竟,Python 是建立在 C 之上的,而 C 是建立在汇编之上的)。
1赞 Nic F 12/23/2021 #3

new_df = old_df.loc[:,pop_columns]

评论

0赞 kory 1/31/2023
这不会从原始数据帧中弹出。
1赞 Keegan Clarke 3/30/2022 #4

如果您不想复制原始 pd。DataFrame,使用列表推导有很好的代码

list_to_pop = ['a', 'b']
[df.pop(col) for col in list_to_pop]