将某些列保留在pandas DataFrame中,删除其他所有内容

时间:2013-05-17 19:00:48

标签: python pandas

说我有数据表

    1  2  3  4  5  6 ..  n
A   x  x  x  x  x  x ..  x
B   x  x  x  x  x  x ..  x
C   x  x  x  x  x  x ..  x

我想减少它,以便我只有第3列和第5列删除所有其他并保持结构。我怎么能用熊猫做到这一点?我想我理解如何删除单个列,但我不知道如何保存一些选择并删除所有其他列。

4 个答案:

答案 0 :(得分:63)

如果你有一个列列表,你可以选择:

In [11]: df
Out[11]:
   1  2  3  4  5  6
A  x  x  x  x  x  x
B  x  x  x  x  x  x
C  x  x  x  x  x  x

In [12]: col_list = [3, 5]

In [13]: df = df[col_list]

In [14]: df
Out[14]:
   3  5
A  x  x
B  x  x
C  x  x

答案 1 :(得分:9)

您可以将新值重新分配给DataFramedf

df = df.loc[:,[3, 5]]

只要原始DataFrame没有其他引用,旧的DataFrame就会收集垃圾。

请注意,使用df.loc时,索引由标签指定。因此,35以上不是序数,它们代表列的标签名称。如果您希望按顺序索引指定列,请使用df.iloc

答案 2 :(得分:5)

  

如何将某些列保留在pandas DataFrame中,删除其他所有内容?

此问题的答案与“如何删除pandas DataFrame中的某些列?”的答案相同。这是到目前为止提到的一些其他选项以及时间安排。

DataFrame.loc

一个简单的选择就是选择,如其他答案所述,

# Setup.
df
   1  2  3  4  5  6
A  x  x  x  x  x  x
B  x  x  x  x  x  x
C  x  x  x  x  x  x

cols_to_keep = [3,5]

df[cols_to_keep]

   3  5
A  x  x
B  x  x
C  x  x

或者,

df.loc[:, cols_to_keep]

   3  5
A  x  x
B  x  x
C  x  x

DataFrame.reindex axis=1'columns'(0.21 +)

但是,我们也有reindex,在最近的版本中,您指定要删除的axis=1

df.reindex(cols_to_keep, axis=1)
# df.reindex(cols_to_keep, axis='columns')

# for versions < 0.21, use
# df.reindex(columns=cols_to_keep)

   3  5
A  x  x
B  x  x
C  x  x

在旧版本上,您也可以使用reindex_axisdf.reindex_axis(cols_to_keep, axis=1)


DataFrame.drop

另一种替代方法是使用drop通过pd.Index.difference选择列:

# df.drop(cols_to_drop, axis=1)
df.drop(df.columns.difference(cols_to_keep), axis=1)

   3  5
A  x  x
B  x  x
C  x  x

性能

enter image description here

在性能方面,这些方法大致相同;对于较小的N,reindex更快,对于较大的N,drop更快。由于Y轴是对数,因此性能是相对的。

设置和代码

import pandas as pd
import perfplot

def make_sample(n):
    np.random.seed(0)
    df = pd.DataFrame(np.full((n, n), 'x'))
    cols_to_keep = np.random.choice(df.columns, max(2, n // 4), replace=False)

    return df, cols_to_keep 

perfplot.show(
    setup=lambda n: make_sample(n),
    kernels=[
        lambda inp: inp[0][inp[1]],
        lambda inp: inp[0].loc[:, inp[1]],
        lambda inp: inp[0].reindex(inp[1], axis=1),
        lambda inp: inp[0].drop(inp[0].columns.difference(inp[1]), axis=1)
    ],
    labels=['__getitem__', 'loc', 'reindex', 'drop'],
    n_range=[2**k for k in range(2, 13)],
    xlabel='N',   
    logy=True,
    equality_check=lambda x, y: (x.reindex_like(y) == y).values.all()
)

答案 3 :(得分:1)

对于那些正在寻找一种方法来就地执行此操作的人:

from pandas import DataFrame
from typing import Set, Any
def remove_others(df: DataFrame, columns: Set[Any]):
    cols_total: Set[Any] = set(df.columns)
    diff: Set[Any] = cols_total - columns
    df.drop(diff, axis=1, inplace=True)

这将创建数据框中所有列和应删除的列的补充。那些可以安全地删除。 Drop甚至可以在空集上工作。

>>> df = DataFrame({"a":[1,2,3],"b":[2,3,4],"c":[3,4,5]})
>>> df
   a  b  c
0  1  2  3
1  2  3  4
2  3  4  5

>>> remove_others(df, {"a","b","c"})
>>> df
   a  b  c
0  1  2  3
1  2  3  4
2  3  4  5

>>> remove_others(df, {"a"})
>>> df
   a
0  1
1  2
2  3

>>> remove_others(df, {"a","not","existent"})
>>> df
   a
0  1
1  2
2  3