448

列の選択に基づいて、既存のデータフレームからビューまたはデータフレームを作成したいと思います。

たとえば、 2つを除くすべての列を保持するデータフレームdf2からデータフレームを作成したいと思います。df1次のことを試しましたが、うまくいきませんでした。

import numpy as np
import pandas as pd

# Create a dataframe with columns A,B,C and D
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

# Try to create a second dataframe df2 from df with all columns except 'B' and D
my_cols = set(df.columns)
my_cols.remove('B').remove('D')

# This returns an error ("unhashable type: set")
df2 = df[my_cols]

私は何が間違っているのですか?おそらくもっと一般的には、パンダはデータフレームからの任意の列のセットの選択と除外をサポートするためにどのようなメカニズムが必要ですか?

4

9 に答える 9

646

不要な列を削除するか、必要な列を選択することができます

# Using DataFrame.drop
df.drop(df.columns[[1, 2]], axis=1, inplace=True)

# drop by Name
df1 = df1.drop(['B', 'C'], axis=1)

# Select the ones you want
df1 = df[['a','d']]
于 2015-03-28T15:54:50.590 に答える
209

と呼ばれる新しいインデックスメソッドがありdifferenceます。引数として渡された列が削除された元の列を返します。

Bここでは、結果を使用して列を削除しDますdf

df2 = df[df.columns.difference(['B', 'D'])]

これはセットベースの方法であるため、列名が重複すると問題が発生し、列の順序が変更される可能性があることに注意してください。


利点drop:列のリストのみが必要な場合は、データフレーム全体のコピーを作成しません。たとえば、列のサブセットに重複をドロップするには、次のようにします。

# may create a copy of the dataframe
subset = df.drop(['B', 'D'], axis=1).columns

# does not create a copy the dataframe
subset = df.columns.difference(['B', 'D'])

df = df.drop_duplicates(subset=subset)
于 2016-05-25T15:12:27.937 に答える
131

ループでドロップまたはフィルタリングせずに、別のオプション:

import numpy as np
import pandas as pd

# Create a dataframe with columns A,B,C and D
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

# include the columns you want
df[df.columns[df.columns.isin(['A', 'B'])]]

# or more simply include columns:
df[['A', 'B']]

# exclude columns you don't want
df[df.columns[~df.columns.isin(['C','D'])]]

# or even simpler since 0.24
# with the caveat that it reorders columns alphabetically 
df[df.columns.difference(['C', 'D'])]
于 2018-07-30T20:41:25.670 に答える
81

それをセットに変換する必要はありません。

cols = [col for col in df.columns if col not in ['B', 'D']]
df2 = df[cols]
于 2013-11-18T02:25:39.110 に答える
22

組み込みDataFrame.filter関数もご覧ください。

ミニマルだが貪欲なアプローチ(与えられたdfには十分):

df.filter(regex="[^BD]")

保守的/怠惰なアプローチ(完全一致のみ):

df.filter(regex="^(?!(B|D)$).*$")

保守的で一般的:

exclude_cols = ['B','C']
df.filter(regex="^(?!({0})$).*$".format('|'.join(exclude_cols)))
于 2014-10-14T09:02:31.400 に答える
11

A、B、C、Dの4つの列があります

新しいデータフレームに必要な列を選択するためのより良い方法は次のとおりです。-

df2 = df1[['A','D']]

代わりに列番号を使用する場合は、次を使用してください。-

df2 = df1[[0,3]]
于 2018-06-18T13:56:12.280 に答える
9

あなたはただあなたをに変換する必要がありsetますlist

import pandas as pd
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
my_cols = set(df.columns)
my_cols.remove('B')
my_cols.remove('D')
my_cols = list(my_cols)
df2 = df[my_cols]
于 2013-02-18T16:32:43.187 に答える
7

列のリストを除外するコピーを作成する方法は次のとおりです。DataFrame

df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
df2 = df.drop(['B', 'D'], axis=1)

ただし、注意してください。dfあなたはあなたの質問の中で見解に言及し、あなたが変更した場合、あなたも変更したいと思うことを示唆していますdf2。(データベース内のビューのように。)

この方法ではそれは達成されません。

>>> df.loc[0, 'A'] = 999 # Change the first value in df
>>> df.head(1)
     A         B         C         D
0  999 -0.742688 -1.980673 -0.920133
>>> df2.head(1) # df2 is unchanged. It's not a view, it's a copy!
          A         C
0  0.251262 -1.980673

これは@piggyboxのメソッドにも当てはまることに注意してください。(その方法は素晴らしく、洗練されていて、Pythonicですが、私はそれをやっていません!!)

ビューとコピーの詳細については、このSOの回答と、その回答が参照しているPandasドキュメントのこの部分を参照してください。

于 2014-08-23T18:45:39.123 に答える
5

同様に、ファイルを読み取るときに、不要なデータをメモリに無駄に読み込んで後で破棄​​するのではなく、列を事前に除外したい場合があります。

pandas 0.20.0以降、usecolscallablesを受け入れるようになりました。1 この更新により、列を読み取るためのより柔軟なオプションが可能になります。

skipcols = [...]
read_csv(..., usecols=lambda x: x not in skipcols)

後者のパターンは、基本的に従来のusecols方法の逆であり、指定された列のみがスキップされます。


与えられた

ファイル内のデータ

import numpy as np
import pandas as pd


df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

filename = "foo.csv"
df.to_csv(filename)

コード

skipcols = ["B", "D"]
df1 = pd.read_csv(filename, usecols=lambda x: x not in skipcols, index_col=0)
df1

出力

          A         C
0  0.062350  0.076924
1 -0.016872  1.091446
2  0.213050  1.646109
3 -1.196928  1.153497
4 -0.628839 -0.856529
...

詳細

DataFrameがファイルに書き込まれました。その後、別のDataFrameとして読み戻され、不要な列(BおよびD)がスキップされるようになりました。

OPの状況では、データはすでに作成されているため、より適切なアプローチは、既存のオブジェクトから不要な列を削除する、受け入れられた回答であることに注意してください。ただし、ここで紹介する手法は、ファイルからDataFrameにデータを直接読み取る場合に最も役立ちます。

この号では「skipcols」オプションのリクエストがあり、後ので対処されました。

于 2017-11-22T02:06:00.470 に答える