パンダのDataFrame列ヘッダーからリストを取得する


1015

パンダのDataFrameから列ヘッダーのリストを取得したいのですが。DataFrameはユーザー入力から取得されるため、列がいくつあるか、または何が呼び出されるかはわかりません。

たとえば、次のようなDataFrameが与えられたとします。

>>> my_dataframe
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

私はこのようなリストを取得したいと思います:

>>> header_list
['y', 'gdp', 'cap']

回答:


1646

次のようにして、値をリストとして取得できます。

list(my_dataframe.columns.values)

また、次のように使用することもできます(Ed Chumの回答に示すように):

list(my_dataframe)

42
このドキュメントにcolumns属性がないのはなぜですか?
Tjorriemorrie 2014年

@Tjorriemorrie:よくわかりません。ドキュメントを自動的に生成する方法に関係している可能性があります。これは、かかわらず、他の場所に記載されている:pandas.pydata.org/pandas-docs/stable/...
シメオンフィッセル

8
のようなものを期待していたでしょうdf.column_names()。この答えはまだ正しいですか、それとも時代遅れですか?
alvas、2016年

1
@alvasには他にもさまざまな方法がありますが(このページの他の回答を参照)、私が知る限り、データフレームに直接リストを作成するメソッドはありません。
Simeon Visser 2016年

19
重要なことに、これにより列の順序が保持されます。
WindChimes 2016年

402

最もパフォーマンスの高い組み込みのメソッドがあります。

my_dataframe.columns.values.tolist()

.columnsインデックスを.columns.values返し、配列を返します。これには.tolistリストを返すヘルパー関数があります。

パフォーマンスがそれほど重要でない場合、Indexオブジェクトは.tolist()直接呼び出すことができるメソッドを定義します。

my_dataframe.columns.tolist()

パフォーマンスの違いは明らかです。

%timeit df.columns.tolist()
16.7 µs ± 317 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit df.columns.values.tolist()
1.24 µs ± 12.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

タイピングを憎む人のために、あなただけ呼び出すことができますlist上のdfように、:

list(df)

4
反対票を投じなかったが、説明したい:実装の詳細に依存せず、DataFrameの「パブリックインターフェイス」を使用する。df.keys()の美しさについて考えてみましょう
Sascha Gottfried

3
@SaschaGottfriedイテラブルの実装はDataFrame初日から変更されていません:pandas.pydata.org/pandas-docs/stable/basics.html#iteration。DataFrameから返される反復可能オブジェクトは常に列であったためfor col in df:、開発者がメルトダウンを持っている場合を除き、常に同じように動作するlist(df)はずです。注df.keys()列ですキーを返す辞書のような構造の内部実装に呼びかけています。不可解な反対投票は、SOで予想される付随的な損害なので心配しないでください
EdChum

columns属性の実装の詳細を参照していました。1時間前、私は呼び出し元が内部オブジェクトモデルのナビゲートに依存するべきではないことを促進するデメテルの法則について読みました。 list(df)明示的な型変換を行います。注目すべき副作用:データフレームサイズdf.keys()メソッドを使用すると実行時間とメモリ消費が増加すること は、のdictのような性質の一部ですDataFrame。特筆すべき事実:の実行時間df.keys()は、データフレームのサイズに関係なくかなり一定です-パンダ開発者の責任の一部です。
Sascha Gottfried、

1
@SaschaGottfried私はこれを私の答えに追加し、誰もこれを含めていないのであなたが見ているとあなたが信じることができます
EdChum

1
与えられた回答とコメントで価値を確認できます。何も変更する必要はありません。
Sascha Gottfried、

89

いくつかの簡単なテストを行いましたが、おそらく当然のことながら、組み込みバージョンdataframe.columns.values.tolist()が最も高速です。

In [1]: %timeit [column for column in df]
1000 loops, best of 3: 81.6 µs per loop

In [2]: %timeit df.columns.values.tolist()
10000 loops, best of 3: 16.1 µs per loop

In [3]: %timeit list(df)
10000 loops, best of 3: 44.9 µs per loop

In [4]: % timeit list(df.columns.values)
10000 loops, best of 3: 38.4 µs per loop

(私はまだそれでも本当に好きなlist(dataframe)ので、EdChumに感謝します!)


47

(パンダ0.16.0によって)さらにシンプルになります:

df.columns.tolist()

列名がリストに表示されます。


37
>>> list(my_dataframe)
['y', 'gdp', 'cap']

デバッガーモードでデータフレームの列を一覧表示するには、リスト内包表記を使用します。

>>> [c for c in my_dataframe]
['y', 'gdp', 'cap']

ちなみに、次のコマンドを使用するだけで、並べ替えられたリストを取得できますsorted

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']

ことlist(df)だけで自動インクリメントデータフレームで動作しますか?それともすべてのデータフレームで機能しますか?
alvas、2016年

2
すべてのために働くべきです。ただし、デバッガーでは、リスト内包表記を使用する必要があります[c for c in df]
Alexander

25

これまでのところこれを見たことがないことに驚いたので、ここに残しておきます。

拡張イテラブルアンパッキング(python3.5 +):[*df]とフレンド

展開の一般化(PEP 448)がPython 3.5で導入されました。したがって、以下の操作はすべて可能です。

df = pd.DataFrame('x', columns=['A', 'B', 'C'], index=range(5))
df

   A  B  C
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x 

あなたが欲しいならlist...

[*df]
# ['A', 'B', 'C']

または、必要に応じてset

{*df}
# {'A', 'B', 'C'}

または、必要に応じてtuple

*df,  # Please note the trailing comma
# ('A', 'B', 'C')

または、結果をどこかに保存したい場合は、

*cols, = df  # A wild comma appears, again
cols
# ['A', 'B', 'C']

...あなたがコーヒーをタイピング音に変換するような人なら、まあ、これはあなたのコーヒーをより効率的に消費するでしょう;)

PS:パフォーマンスが重要な場合は、上記のソリューションを廃止して、

df.columns.to_numpy().tolist()
# ['A', 'B', 'C']

これはEd Chumの回答に似て.to_numpy()いますが、の使用が推奨されるv0.24用に更新されています.values。詳細については(私が)この回答を参照 してください。

ビジュアルチェック
これは他の回答で説明されているので、反復可能なアンパッキングを利用できます(明示的なループは必要ありません)。

print(*df)
A B C

print(*df, sep='\n')
A
B
C

他の方法の批評

for1行で実行できる操作に明示的なループを使用しないでください(リスト内包表記は問題ありません)。

次に、を使用sorted(df) しても、列の元の順序保持されません。そのためには、list(df)代わりに使用する必要があります。

次に、list(df.columns)およびlist(df.columns.values)(現在のバージョン、v0.24のような)が悪いの提案です。Index(から返されるdf.columns)とNumPy配列(によって返されるdf.columns.values)の両方.tolist()が、より高速で慣用的なメソッドを定義しています。

最後に、リスト化、つまり拡張アンパッキングlist(df)が利用できないpython <= 3.4の前述のメソッドの簡潔な代替手段としてのみ使用する必要があります。



18

興味深いですdf.columns.values.tolist()が、約3倍高速ですdf.columns.tolist()が、同じだと思いました。

In [97]: %timeit df.columns.values.tolist()
100000 loops, best of 3: 2.97 µs per loop

In [98]: %timeit df.columns.tolist()
10000 loops, best of 3: 9.67 µs per loop

2
タイミングはこの回答ですでにカバーされています。不一致の理由.valuesは、基になるnumpy配列を返すためです。numpyで何かを行うと、ほとんどの場合、pandasで直接同じことを行うよりも高速です。
cs95

17

A データフレームは、辞書のようなオブジェクトの「キー」を反復処理の規則に従います。

my_dataframe.keys()

キー/列のリストを作成する-オブジェクトメソッドto_list()とPythonの方法

my_dataframe.keys().to_list()
list(my_dataframe.keys())

DataFrameの基本的な反復は列ラベルを返します

[column for column in my_dataframe]

列のラベルを取得するためだけに、DataFrameをリストに変換しないでください。便利なコードサンプルを探している間、考えを止めないでください。

xlarge = pd.DataFrame(np.arange(100000000).reshape(10000,10000))
list(xlarge) #compute time and memory consumption depend on dataframe size - O(N)
list(xlarge.keys()) #constant time operation - O(1)

2
私のテストdf.columnsは、よりもはるかに高速であることを示していdf.keys()ます。なぜそれらが同じものに機能と属性の両方を持っているのかわかりません(まあ、パンダで何かをするための10の異なる方法を見たのはこれが初めてではありません)。
cs95

1
私の答えの意図は、DataFrameから列ラベルを照会するいくつかの方法を示し、パフォーマンスのアンチパターンを強調することでした。それにもかかわらず、私はあなたのコメントが好きで、あなたの最近の答えを支持しました-彼らはソフトウェア工学の観点から価値を提供するからです。
Sascha Gottfried

14

ノートブック

IPythonノートブックでのデータ探索の場合、私の推奨する方法は次のとおりです。

sorted(df)

アルファベット順に並べられたリストが読みやすくなります。

コードリポジトリ内

コードでは、それを行うことがより明示的であると思います

df.columns

それはあなたが何をしているのかあなたのコードを読んでいる他の人に告げるからです。


sorted(df)順序を変更します。注意して使用してください。
cs95

@coldspeedこれについては触れますが、「アルファベット順に並べられたリストが読みやすくなります。」
firelynx

9
%%timeit
final_df.columns.values.tolist()
948 ns ± 19.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
list(final_df.columns)
14.2 µs ± 79.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(final_df.columns.values)
1.88 µs ± 11.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
final_df.columns.tolist()
12.3 µs ± 27.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(final_df.head(1).columns)
163 µs ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

3

Simeon Visserの回答によると...

list(my_dataframe.columns.values) 

または

list(my_dataframe) # for less typing.

しかし、私が最もスイートスポットだと思います:

list(my_dataframe.columns)

それは明示的であり、同時に不必要に長くはありません。


「それは明白であり、同時に不必要に長くはない。」同意しません。直接list呼び出すdf(簡潔にするなど)場合を除き、呼び出しにはメリットがありません。.columns属性にアクセスするとIndextolist()メソッドが定義されているオブジェクトが返され、それを呼び出すと、をリストするよりも慣用的になりIndexます。完全を期すためだけにイディオムを混ぜることは良い考えではありません。取得した配列をリスト化する場合も同様です.values
cs95


3

これにより、リスト内の列の名前が得られます。

list(my_dataframe.columns)

tolist()と呼ばれる別の関数も使用できます。

my_dataframe.columns.tolist()

これはすでに他の回答でカバーされています。最初のソリューションはイディオムも混在させますが、これは素晴らしいアイデアではありません。別の回答の下で私のコメントを参照してください。
cs95

2

質問は追加の説明に値すると思います。

@fixxxerが述べたように、答えはプロジェクトで使用しているパンダのバージョンによって異なります。pd.__version__コマンドで取得できます。

私のような何らかの理由で(debian jessieでは0.14.1を使用しています)、0.16.0より古いバージョンのパンダを使用している場合は、以下を使用する必要があります。

df.keys().tolist()df.columnsまだ実装されているメソッドがないためです。

このキー方法の利点は、新しいバージョンのパンダでも機能するため、より普遍的であることです。


keys()の欠点は、属性のルックアップではなく関数呼び出しであるため、常に遅くなることです。もちろん、一定時間のアクセスでは、このような違いを気にする人はいませんが、とにかく言及する価値はあると思います。df.columnsは、ヘッダーにアクセスするためのより一般的に受け入れられているイディオムになりました。
cs95

1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n

6
リスト内包表記に置き換えてください。
Sascha Gottfried

4
最初の3行を次のように変更します[n for n in dataframe.columns]
Anton Protopopov

1行で簡単に実行できる操作で、このような問題をすべて解決したいのはなぜですか。
cs95

0

上記で提供されたソリューションは素晴らしいですが。また、frame.column_names()のようなものがパンダの関数であると期待しますが、そうではないので、次の構文を使用するとよいでしょう。「tolist」関数を呼び出すことにより、パンダを適切に使用しているという感覚をなんとか維持します。frame.columns.tolist()

frame.columns.tolist() 

0

DataFrameにインデックスまたはマルチインデックスがあり、それらも列名として含める場合:

names = list(filter(None, df.index.names + df.columns.values.tolist()))

そのような単純な操作で不必要なパフォーマンスヒットが発生するreset_index()の呼び出しを回避します。

データフレームインデックスが主キー/一意キーにマップされているデータベースからデータを送っているので、これがより頻繁に必要になりますが、実際には私にとっては単なる「列」です。パンダがこのようなもののための組み込みのメソッドを持っていることはおそらく意味があります(完全に私がそれを逃した可能性があります)。


-1

このソリューションは、オブジェクトmy_dataframeのすべての列をリストします。

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