新しい行を追加し、既存の列に基づいて新しい列を追加したいと思います。たとえば、次のデータフレームがあるとします。
A B
1 a
2 b
3 c
4 b
そして、キーとして一意の列Bの値を持つ辞書。各キーは値のリストに関連付けられています。これらの値は、新しい行と列に使用されます。{a: [x, y, z], b: [x, w, r], c: [x, q]}
変換により、次のデータフレームが生成されます。
A C
1 x
1 y
1 z
2 x
2 w
2 r
3 x
3 q
4 x
4 w
4 r
新しい列を追加する方法は知っていますが、行を複製しようとして立ち往生しています。この問題に対する最も効率的な解決策は何ですか?既存のデータフレームを更新しますか、それとも新しいデータフレームを作成しますか?
更新
この操作は、Daskを使用する大規模なデータフレーム(2,000万行以上)で使用されます。
私は新しいの作成をお勧めmap
、np.repeat
とchain.from_iterable
:
d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
s = df['B'].map(d)
lens = [len(x) for x in s]
from itertools import chain
df = pd.DataFrame({
'A' : df['A'].values.repeat(lens),
'C' : list(chain.from_iterable(s.values.tolist()))
})
print (df)
A C
0 1 x
1 1 y
2 1 z
3 2 x
4 2 w
5 2 r
6 3 x
7 3 q
8 4 x
9 4 w
10 4 r
辞書の一部の値が一致しない場合に機能するより一般的なソリューション:
map
欠落した値を返すため、最初のソリューションはエラーを返します。
TypeError:タイプ 'NoneType'のオブジェクトにlen()がありません
print (df)
A B
0 1 d <- change data
1 2 b
2 3 c
3 4 b
d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
s = [d.get(x, [x]) for x in df['B']]
print (s)
[['d'], ['x', 'w', 'r'], ['x', 'q'], ['x', 'w', 'r']]
lens = [len(x) for x in s]
from itertools import chain
df = pd.DataFrame({
'A' : df['A'].values.repeat(lens),
'B' : list(chain.from_iterable(s))
})
print (df)
A B
0 1 d
1 2 x
2 2 w
3 2 r
4 3 x
5 3 q
6 4 x
7 4 w
8 4 r
を使用するためdask
、別の解決策は次のようになります。
d = {'a': ['x', 'y', 'z'], 'b': ['x', 'w', 'r'], 'c': ['x', 'q']}
df1 = pd.DataFrame([(k, y) for k, v in d.items() for y in v], columns=['B','C'])
print (df1)
B C
0 a x
1 a y
2 a z
3 b x
4 b w
5 b r
6 c x
7 c q
df = df.merge(df1, on='B', how='left')
print (df)
A B C
0 1 a x
1 1 a y
2 1 a z
3 2 b x
4 2 b w
5 2 b r
6 3 c x
7 3 c q
8 4 b x
9 4 b w
10 4 b r
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加