【问题标题】:Selecting a subset of columns without copying选择列的子集而不复制
【发布时间】:2017-11-27 09:38:57
【问题描述】:

我想从 DataFrame 中选择列的子集而不复制数据。从 this answer 看来,如果列具有不同的 dtype,那似乎是不可能的。有人可以确认吗?对我来说,似乎必须有一种方法,因为该功能非常重要。

例如,df.loc[:, ['a', 'b']] 生成一个副本。

【问题讨论】:

  • 如果您引用的示例表明它是正确的,您是否尝试过它的工作原理?
  • 我已经尝试了 df.loc 示例并将 _is_view 设置为 false。此外,赋值不会传播到原始 DataFrame。因此,它会生成一个副本。 (我编辑了问题以反映这一点。)
  • 我闻到了一个 XY 问题......你想在这里实现什么?
  • 例如,选择列的子集,然后使用itertuples() 创建一个列表作为参数传递给pyodbc 的executemany 函数。
  • 对于大型数据集来说这是一个明显的问题!并非所有揭示不良设计的问题都是 XY 问题。

标签: python pandas dataframe indexing


【解决方案1】:

这篇文章仅适用于在所有列中具有相同 dtype 的数据框。

如果在.iloc 中使用切片,要选择的列彼此之间有规律的步幅是可能的。因此,总是可以选择任意两列,但对于多于两列,我们需要在它们之间有规律的跨步。在所有这些情况下,我们都需要知道它们的列 ID 和步长。

让我们尝试通过一些示例案例来理解这些。

案例 #1:从第 0 列 ID 开始的两列

In [47]: df1
Out[47]: 
   a  b  c  d
0  5  0  3  3
1  7  3  5  2
2  4  7  6  8

In [48]: np.array_equal(df1.loc[:, ['a', 'b']], df1.iloc[:,0:2])
Out[48]: True

In [50]: np.shares_memory(df1, df1.iloc[:,0:2]) # confirm view
Out[50]: True

案例 #2:从第一个 col ID 开始的两列

In [51]: df2
Out[51]: 
   a0  a  a1  a2  b  c  d
0   8  1   6   7  7  8  1
1   5  8   4   3  0  3  5
2   0  2   3   8  1  3  3

In [52]: np.array_equal(df2.loc[:, ['a', 'b']], df2.iloc[:,1::3])
Out[52]: True

In [54]: np.shares_memory(df2, df2.iloc[:,1::3]) # confirm view
Out[54]: True

案例 #2:从第一个 col ID 开始的三列和 2 列的步幅

In [74]: df3
Out[74]: 
   a0  a  a1  b  b1  c  c1  d  d1
0   3  7   0  1   0  4   7  3   2
1   7  2   0  0   4  5   5  6   8
2   4  1   4  8   1  1   7  3   6

In [75]: np.array_equal(df3.loc[:, ['a', 'b', 'c']], df3.iloc[:,1:6:2])
Out[75]: True

In [76]: np.shares_memory(df3, df3.iloc[:,1:6:2]) # confirm view
Out[76]: True

选择 4 列:

In [77]: np.array_equal(df3.loc[:, ['a', 'b', 'c', 'd']], df3.iloc[:,1:8:2])
Out[77]: True

In [78]: np.shares_memory(df3, df3.iloc[:,1:8:2])
Out[78]: True

【讨论】:

  • 我忘了说列的dtypes是不同的。我编辑了问题。
  • @Konstantin 您应该在前面提到过。不要认为这适用于不同的数据类型。为未来的读者保留这篇文章,以了解相同 dtype 案例的常规案例。
  • 我不知道你为什么假设所有的数据类型都是平等的?这是一个非常狭窄的用例。不过,很抱歉浪费您的时间。
猜你喜欢
  • 2012-03-23
  • 1970-01-01
  • 2015-03-21
  • 2020-08-01
  • 2021-08-06
  • 2016-04-24
  • 2013-11-26
  • 1970-01-01
相关资源
最近更新 更多