pandasを使用して辞書の列を個別の列に分割/展開する 質問する

pandasを使用して辞書の列を個別の列に分割/展開する 質問する

データベースにデータが保存されていますpostgreSQL。Python2.7 を使用してこのデータをクエリし、Pandas DataFrame に変換しています。ただし、このデータフレームの最後の列には値の辞書が含まれています。DataFrame はdf次のようになります。

Station ID     Pollutants
8809           {"a": "46", "b": "3", "c": "12"}
8810           {"a": "36", "b": "5", "c": "8"}
8811           {"b": "2", "c": "7"}
8812           {"c": "11"}
8813           {"a": "82", "c": "15"}

この列を別々の列に分割して、DataFrame `df2 が次のようになるようにする必要があります。

Station ID     a      b       c
8809           46     3       12
8810           36     5       8
8811           NaN    2       7
8812           NaN    NaN     11
8813           82     NaN     15

私が抱えている大きな問題は、リストの長さが同じではないことです。しかし、すべてのリストには、同じ 3 つの値 (「a」、「b」、「c」) しか含まれていません。また、それらは常に同じ順序 (「a」が最初、「b」が 2 番目、「c」が 3 番目) で表示されます。

次のコードは以前は機能し、まさに私が望んでいたもの (df2) を返していました。

objs = [df, pandas.DataFrame(df['Pollutant Levels'].tolist()).iloc[:, :3]]
df2 = pandas.concat(objs, axis=1).drop('Pollutant Levels', axis=1)
print(df2)

先週このコードを実行したところ、問題なく動作していました。しかし、今はコードが壊れていて、[4]行目で次のエラーが発生します。

IndexError: out-of-bounds on slice (end) 

コードに変更を加えていないのに、エラーが発生しています。これは、私の方法が堅牢でないか適切でなかったためだと思います。

このリストの列を個別の列に分割する方法について、ご提案やご指導をいただければ幸いです。

.tolist()編集:私のコードは 1 つの Unicode 文字列であるため、 および .apply メソッドが機能していないと思います。

#My data format 
u{'a': '1', 'b': '2', 'c': '3'}

#and not
{u'a': '1', u'b': '2', u'c': '3'}

データはpostgreSQLこの形式でデータベースからインポートされます。この問題に関して何か助言やアイデアはありますか? Unicode を変換する方法はありますか?

ベストアンサー1

文字列を実際の辞書に変換するには、 を実行します。その後、以下のソリューションを使用して、辞書を別の列に変換できます。df['Pollutant Levels'].map(ast.literal_eval)


小さな例を使用すると、次のように使用できます.apply(pd.Series)

In [2]: df = pd.DataFrame({'a':[1,2,3], 'b':[{'c':1}, {'d':3}, {'c':5, 'd':6}]})

In [3]: df
Out[3]:
   a                   b
0  1           {u'c': 1}
1  2           {u'd': 3}
2  3  {u'c': 5, u'd': 6}

In [4]: df['b'].apply(pd.Series)
Out[4]:
     c    d
0  1.0  NaN
1  NaN  3.0
2  5.0  6.0

これをデータフレームの残りの部分と結合するには、concat他の列を上記の結果と組み合わせます。

In [7]: pd.concat([df.drop(['b'], axis=1), df['b'].apply(pd.Series)], axis=1)
Out[7]:
   a    c    d
0  1  1.0  NaN
1  2  NaN  3.0
2  3  5.0  6.0

あなたのコードを使用すると、次の部分を省略しても機能しますiloc:

In [15]: pd.concat([df.drop('b', axis=1), pd.DataFrame(df['b'].tolist())], axis=1)
Out[15]:
   a    c    d
0  1  1.0  NaN
1  2  NaN  3.0
2  3  5.0  6.0

おすすめ記事