辞書のリストをpandas DataFrameに変換するにはどうすればよいですか?
他の答えは正しいですが、これらの方法の利点と制限に関してはあまり説明されていません。この投稿の目的は、さまざまな状況でのこれらの方法の例を示し、使用する場合(および使用しない場合)について話し合い、代替案を提案することです。
データの構造と形式に応じて、3つすべての方法が機能する場合や、一部の方法が他の方法よりも機能する場合、または一部がまったく機能しない場合があります。
非常に不自然な例を考えてみましょう。
np.random.seed(0)
data = pd.DataFrame(
np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')
print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
このリストは、すべてのキーが存在する「レコード」で構成されています。これは、遭遇する可能性のある最も単純なケースです。
# The following methods all produce the same output.
pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
辞書の向きに関する単語:orient='index'
/'columns'
続行する前に、さまざまなタイプの辞書の向きを区別し、パンダでサポートすることが重要です。「列」と「インデックス」の2つの主要なタイプがあります。
orient='columns'
「列」方向のディクショナリのキーは、対応するDataFrameの列に対応します。
たとえば、data
上記は「列」オリエントです。
data_c = [
{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
pd.DataFrame.from_dict(data_c, orient='columns')
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
注:を使用しているpd.DataFrame.from_records
場合、方向は「列」であると見なされ(他に指定することはできません)、辞書はそれに応じて読み込まれます。
orient='index'
この方向では、キーはインデックス値に対応すると想定されます。この種のデータはに最適ですpd.DataFrame.from_dict
。
data_i ={
0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}
pd.DataFrame.from_dict(data_i, orient='index')
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
このケースはOPでは考慮されていませんが、知っておくと役に立ちます。
カスタムインデックスの設定
結果のDataFrameにカスタムインデックスが必要な場合は、index=...
引数を使用して設定できます。
pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])
A B C D
a 5 0 3 3
b 7 9 3 5
c 2 4 7 6
これはでサポートされていませんpd.DataFrame.from_dict
。
欠落しているキー/列の処理
すべてのメソッドは、キー/列の値が欠落している辞書を処理するときにすぐに使用できます。例えば、
data2 = [
{'A': 5, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'F': 5},
{'B': 4, 'C': 7, 'E': 6}]
# The methods below all produce the same output.
pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)
A B C D E F
0 5.0 NaN 3.0 3.0 NaN NaN
1 7.0 9.0 NaN NaN NaN 5.0
2 NaN 4.0 7.0 NaN 6.0 NaN
列のサブセットの読み取り
「すべての列を読みたくない場合」これは、columns=...
パラメーターを使用して簡単に指定できます。
たとえば、data2
上記の例の辞書から、列「A」、「D」、および「F」のみを読み取りたい場合は、リストを渡すことでそれを行うことができます。
pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])
A D F
0 5.0 3.0 NaN
1 7.0 NaN 5.0
2 NaN NaN NaN
これはpd.DataFrame.from_dict
、デフォルトの方向「列」ではサポートされていません。
pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])
ValueError: cannot use columns parameter with orient='columns'
行のサブセットの読み取り
これらのメソッドでは直接サポートされていません。データを繰り返し処理し、繰り返し処理しながら逆方向の削除を実行する必要があります。たとえば、上から0 番目と2 番目の行のみを抽出するには、次のdata2
ように使用できます。
rows_to_select = {0, 2}
for i in reversed(range(len(data2))):
if i not in rows_to_select:
del data2[i]
pd.DataFrame(data2)
# pd.DataFrame.from_dict(data2)
# pd.DataFrame.from_records(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
上記の方法の強力で堅牢な代替手段json_normalize
は、辞書(レコード)のリストを処理する関数であり、さらにネストされた辞書を処理することもできます。
pd.io.json.json_normalize(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
pd.io.json.json_normalize(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
ここでも、渡されるデータはjson_normalize
辞書のリスト(レコード)形式である必要があることに注意してください。
前述のように、json_normalize
ネストされた辞書を処理することもできます。ドキュメントからの例を以下に示します。
data_nested = [
{'counties': [{'name': 'Dade', 'population': 12345},
{'name': 'Broward', 'population': 40000},
{'name': 'Palm Beach', 'population': 60000}],
'info': {'governor': 'Rick Scott'},
'shortname': 'FL',
'state': 'Florida'},
{'counties': [{'name': 'Summit', 'population': 1234},
{'name': 'Cuyahoga', 'population': 1337}],
'info': {'governor': 'John Kasich'},
'shortname': 'OH',
'state': 'Ohio'}
]
pd.io.json.json_normalize(data_nested,
record_path='counties',
meta=['state', 'shortname', ['info', 'governor']])
name population state shortname info.governor
0 Dade 12345 Florida FL Rick Scott
1 Broward 40000 Florida FL Rick Scott
2 Palm Beach 60000 Florida FL Rick Scott
3 Summit 1234 Ohio OH John Kasich
4 Cuyahoga 1337 Ohio OH John Kasich
meta
とrecord_path
引数の詳細については、ドキュメントをご覧ください。
まとめ
サポートされている機能/機能とともに、上記で説明したすべての方法の表を以下に示します。
*を使用orient='columns'
してから転置すると、と同じ効果が得られorient='index'
ます。