パンダでデータフレームの列スライスを取得する方法


264

CSVファイルから機械学習データを読み込みます。最初の2列は観測値で、残りの列は特徴です。

現在、私は次のことをしています。

data = pandas.read_csv('mydata.csv')

これは次のようなものになります:

data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))

私は2つのデータフレームでは、このデータフレームをスライスしたいと思います:1列を含むab、もう1つは列を含むcde

次のようなものを書くことはできません

observations = data[:'c']
features = data['c':]

私は最善の方法が何であるかわかりません。私は必要pd.Panelですか?

ちなみに、データフレームのインデックス付けはかなり一貫性data['a']data[0]ありません。許可されていますが許可されていません。一方で、data['a':]許可されていませんが許可されていdata[0:]ます。これには実際的な理由はありますか?列がIntによってインデックス付けされている場合、これは本当に混乱します。data[0] != data[0:1]


3
データフレームは本質的であるあなたがDF [...]しかし、いくつかの便利さを行う際のdictはのようなオブジェクト、例えばdf[5:10]行を選択するために追加されました(pandas.pydata.org/pandas-docs/stable/...
ウェス・マッキニー

1
では、この不一致は、利便性を優先する設計上の決定とは何でしょうか。わかりましたが、初心者にはもっと明確にする必要があります。
cpa 2012年

3
利便性をサポートするという設計上の考慮事項により、学習曲線は非常に急になります。一貫性のあるインターフェースを提示するための最初の良いドキュメントがあることを願っています。たとえば、ixインターフェースにのみ注目します。
Yu Shen

回答:


243

2017回答-パンダ0.20:.ixは非推奨になりました。.locを使用

ドキュメント非推奨を参照してください

.locラベルベースのインデックスを使用して、行と列の両方を選択します。ラベルは、インデックスまたは列の値です。でスライスすると.loc、最後の要素が含まれます。

我々は、次の列を持つデータフレームを持っていると仮定しましょう:
foobarquzantcatsatdat

# selects all rows and all columns beginning at 'foo' up to and including 'sat'
df.loc[:, 'foo':'sat']
# foo bar quz ant cat sat

.locPythonリストが行と列の両方に対して行うのと同じスライス表記を受け入れます。スライス表記ありstart:stop:step

# slice from 'foo' to 'cat' by every 2nd column
df.loc[:, 'foo':'cat':2]
# foo quz cat

# slice from the beginning to 'bar'
df.loc[:, :'bar']
# foo bar

# slice from 'quz' to the end by 3
df.loc[:, 'quz'::3]
# quz sat

# attempt from 'sat' to 'bar'
df.loc[:, 'sat':'bar']
# no columns returned

# slice from 'sat' to 'bar'
df.loc[:, 'sat':'bar':-1]
sat cat ant quz bar

# slice notation is syntatic sugar for the slice function
# slice from 'quz' to the end by 2 with slice function
df.loc[:, slice('quz',None, 2)]
# quz cat dat

# select specific columns with a list
# select columns foo, bar and dat
df.loc[:, ['foo','bar','dat']]
# foo bar dat

行と列でスライスできます。たとえば、あなたがラベルに5行を持っている場合はvwxyz

# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
#    foo ant
# w
# x
# y

あなたが使用している場合のように、ラムダ行に適用されます。df['newcol'] = df.apply(lambda row: myfunc(row), axis=1) そして、あなたがすることができますでmyfunc(row){...使用しますrow['foo':'ant']。(による例えば、このStackOverflowの答えの内側に、) myfunc:これらのいずれかが非数値である場合はevalueateすることができますrow['foo':'ant'].apply(lambda x: isinstance(x, str)).any()
pashuteは

4
.ilocの代わりに、今使用する必要があり.locます。修正してください。賛成投票します。
craned

1
@craned-不正解です。Pandasのドキュメントから:.locは主にラベルベースですが、ブール配列と一緒に使用することもできます。アイテムが見つからない場合、.locはKeyErrorを発生させます。同様に、.ilocはインデックスベースのスライスを具体的に参照しています。つまり、この例では、ラベルベースのインデックスを使用し、.locが正しい選択です(基本的には唯一の選択です)。たとえば、位置-行5:10でスライスする場合は、.iloc
user2103050

149

注: .ix Pandas v0.20から非推奨になりました。代わりに、必要に応じて.locまたはを使用する必要があり.ilocます。

DataFrame.ixインデックスは、アクセスしたいものです。少し混乱しますが(Pandasのインデックス作成が時々困惑していることに同意します!)、次のようにすると期待どおりの結果が得られます。

>>> df = DataFrame(np.random.rand(4,5), columns = list('abcde'))
>>> df.ix[:,'b':]
      b         c         d         e
0  0.418762  0.042369  0.869203  0.972314
1  0.991058  0.510228  0.594784  0.534366
2  0.407472  0.259811  0.396664  0.894202
3  0.726168  0.139531  0.324932  0.906575

ここで、.ix [行スライス、列スライス]は解釈されるものです。Pandasのインデックス作成の詳細はこちら:http : //pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced


5
パンダの範囲には両方のエンドポイントが含まれることに注意してください。つまり>>>data.ix[:, 'a':'c'] a b c 0 0.859192 0.881433 0.843624 1 0.744979 0.427986 0.177159
ホッパー

21
このように複数の列を渡すことができますdf.ix[:,[0,3,4]]
user602599 2014

3
@Karmel:上記の出力にコピー/貼り付けエラーのように見えます。たぶん、あなたは意味しましたdf.ix[:,'b':'e']か?
ChaimG

6
loc代わりに使用することをおix
勧めし

5
このような古い回答は削除する必要があります。.ixは非推奨であり、使用しないでください。
Ted Petrou 2017年

75

例として、seabornパッケージのタイタニックデータセットを使用してみましょう

# Load dataset (pip install seaborn)
>> import seaborn.apionly as sns
>> titanic = sns.load_dataset('titanic')

列名を使用する

>> titanic.loc[:,['sex','age','fare']]

列インデックスの使用

>> titanic.iloc[:,[2,3,6]]

ixの使用(Pandasより古い<.20バージョン)

>> titanic.ix[:,[‘sex’,’age’,’fare’]]

または

>> titanic.ix[:,[2,3,6]]

reindexメソッドの使用

>> titanic.reindex(columns=['sex','age','fare'])

6
Pandas 0.20では:.ixは非推奨です。
Shihe Zhang 2017

非推奨の警告:Passing list-likes to .loc or [] with any missing label will raise KeyError in the future, you can use .reindex() as an alternative.使用する場合df.loc[:, some_list_of_columns]
Marc Maxmeister

35

また、DataFrame

データ

あなたの例のように、列aとdのみ(1番目と4番目の列)を抽出する場合、pandasデータフレームからiloc mothodが必要であり、非常に効果的に使用できます。知っておく必要があるのは、抽出する列のインデックスだけです。例えば:

>>> data.iloc[:,[0,3]]

あなたにあげます

          a         d
0  0.883283  0.100975
1  0.614313  0.221731
2  0.438963  0.224361
3  0.466078  0.703347
4  0.955285  0.114033
5  0.268443  0.416996
6  0.613241  0.327548
7  0.370784  0.359159
8  0.692708  0.659410
9  0.806624  0.875476

25

次のDataFrameように、リストの各列の名前を参照することで、aの列に沿ってスライスできます。

data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
data_ab = data[list('ab')]
data_cde = data[list('cde')]

したがって、列「b」から始まるすべてのデータが必要な場合は、data.columnsで「b」のインデックスを見つけて、data [data.columns [1:]]を実行する必要がありますか?それは標準的な操作方法ですか?
cpa 2012年

1
「b」以降のすべての列を選択したいですか?
ブレンダンウッド

はい、または特定の範囲のすべての列を選択します。
cpa 2012年

私自身、パンダは初めてなので、正規のものとは言えません。私はあなたが言ったようにそれをしますが、get_loc関数data.columns' on 'を使用して列 'b'のインデックスなどを決定します。
ブレンダンウッド

20

そして、あなたがここに来て、2つの列の範囲をスライスしてそれらを組み合わせる(私のように)場合、次のようなことができます

op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op

これにより、最初の900列と(すべての)列が3593を超える新しいデータフレームが作成されます(データセットに4000列あると仮定します)。


すばらしい、誰かがこれを試してみました...私は、最初の900列を取得するこの0:899を疑問に思っていました。なぜ、このようにしたのですか?これはPythonのようには感じられません。Pythonで範囲を使用する場合は、常に 'until'ではなく 'until and
include

14

選択的なラベルベース、インデックスベース、選択的な範囲ベースの列スライスなど、さまざまな方法を使用して選択的な列スライスを行う方法を次に示します

In [37]: import pandas as pd    
In [38]: import numpy as np
In [43]: df = pd.DataFrame(np.random.rand(4,7), columns = list('abcdefg'))

In [44]: df
Out[44]: 
          a         b         c         d         e         f         g
0  0.409038  0.745497  0.890767  0.945890  0.014655  0.458070  0.786633
1  0.570642  0.181552  0.794599  0.036340  0.907011  0.655237  0.735268
2  0.568440  0.501638  0.186635  0.441445  0.703312  0.187447  0.604305
3  0.679125  0.642817  0.697628  0.391686  0.698381  0.936899  0.101806

In [45]: df.loc[:, ["a", "b", "c"]] ## label based selective column slicing 
Out[45]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [46]: df.loc[:, "a":"c"] ## label based column ranges slicing 
Out[46]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

In [47]: df.iloc[:, 0:3] ## index based column ranges slicing 
Out[47]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

### with 2 different column ranges, index based slicing: 
In [49]: df[df.columns[0:1].tolist() + df.columns[1:3].tolist()]
Out[49]: 
          a         b         c
0  0.409038  0.745497  0.890767
1  0.570642  0.181552  0.794599
2  0.568440  0.501638  0.186635
3  0.679125  0.642817  0.697628

答えとしてコードを単にダンプするのを避け、それが何をするのか、なぜ説明するのか試してください。あなたのコードは、関連するコーディングの経験がない人にとっては明白ではないかもしれません。回答を編集して、明確化、コンテキスト
SᴀᴍOnᴇᴌᴀ


1

データフレームが次のようになっている場合:

group         name      count
fruit         apple     90
fruit         banana    150
fruit         orange    130
vegetable     broccoli  80
vegetable     kale      70
vegetable     lettuce   125

そしてOUTPUTは

   group    name  count
0  fruit   apple     90
1  fruit  banana    150
2  fruit  orange    130

論理演算子np.logical_notを使用する場合

df[np.logical_not(df['group'] == 'vegetable')]

詳細について

https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html

その他の論理演算子

  1. logical_and(x1、x2、/ [、out、where、...])x1 AND x2の真理値を要素ごとに計算します。

  2. logical_or(x1、x2、/ [、out、where、casting、...])x1 OR x2の真理値を要素ごとに計算します。

  3. logical_not(x、/ [、out、where、Casting、...])NOT xの真理値を要素ごとに計算します。
  4. logical_xor(x1、x2、/ [、out、where、..])x1 XOR x2の真理値を要素ごとに計算します。

0

あなたのデータフレームからの列のサブセットを取得する別の方法は、あなたがすべての行をしたいと仮定すると、行うことを次のようになります。
data[['a','b']]そしてdata[['c','d','e']]
あなたは、数値列インデックスを使用したい場合は、行うことができます
data[data.columns[:2]]し、data[data.columns[2:]]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.