質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

331閲覧

Python DataFrameのセルに複数の値がある場合、その値ごと新しい行にする方法

SnowBallEffect

総合スコア28

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/08/11 08:13

実現したいこと

DataFrameのセルの中に値が一つある場合と複数ある場合があります。例えばこんな感じです。

AgeConsole 1Console 2Console3Console 4
15PS5XBox, Wii UGameboyPS2
16GameCubePS4, GameBoy Color, PS5NaNXbox 360
17PS3, PS5PS4PS VitaNaN

最終的にはこのようにしたいのです:

AgeGame Console Combined
15PS5
15Xbox
15Wii U
15Gameboy
15PS2
16GameCube
16PS4
16GameBoy Color
16PS5
16Xbox 360
17PS3
17PS5
17PS4
17PS Vita
  • ▲▲機能を動作するようにする

該当のソースコード

Python

1import pandas as pd 2game = r"C:\users\Gamer\Desktop\game.xlsx" 3df = pd.read_excel(game) 4 5こちらのエクセルは他にも沢山列があるのですが、割愛致します。 6 7#複数の値がある場合、必ずこのstringがあるので消します _x000D_\n' 8#空白のセルのdtypeは'float'になっているのでstrで変換します。 9 10下記がそのコードです。 11 12df['Console 1'] = df['Console 1'].str.split('_x000D_\n').astype('str').replace('nan', '') 13df['Console 2'] = df['Console 2'].str.split('_x000D_\n').astype('str').replace('nan', '') 14df['Console 3'] = df['Console 3'].str.split('_x000D_\n').astype('str').replace('nan', '') 15 16#ここでゲームコンソールを一つにまとめるので新しい列 Game Console Combinedを作ります。 17df['Game Console Combined'] = df['Console 1'] + df['Console 2'] + df['Console 3] +df['Console 4] 18 19print(df['Game Console Combined'][0]) 20だとこのようにoutputされます。 21 22['PS5']['XBox', 'Wii U']['Gameboy']['PS2'] 23 24上記の例だとitemは5つなので、下記のコードで新しい行が5つ作られるかと思ったら作られず 25print(df.explode('Game Console Combined').head()) 26 27エラーメッセージは出てきません。

試したこと

for console in df['Game Console Combined'].str.split(','):
for type in console:
print(type[1])

これだったら
GameCube
PS4, GameBoy Color PS5

Xbox 360

と出てくるのですが、それでも値が複数あるセルは複数として出てきます。

どうやったら、複数の値があるセルをその値の数だけ行を足し、一つの値があるセルも行に足せるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Python

1df = pd.DataFrame({'Age':[15,16,17],'Console1':['PS5','GameCube','PS3,PS5'],'Console2':['XBox,Wii U','PS4,GameBoy Color,PS5','PS4'],'Console3':['Gameboy',np.nan,'PS Vita'],'Console4':['PS2','Xbox360',np.nan]}) 2print(df) 3# Age Console1 Console2 Console3 Console4 4#0 15 PS5 XBox,Wii U Gameboy PS2 5#1 16 GameCube PS4,GameBoy Color,PS5 NaN Xbox360 6#2 17 PS3,PS5 PS4 PS Vita NaN 7 8df = df.applymap(lambda x: x.split(',') if ',' in str(x) else x) 9df = df.explode('Console1').explode('Console2') 10df = pd.concat([df[['Age', i]].rename(columns={i:'Game Console Combined'}) for i in df.columns if i != 'Age']).dropna().drop_duplicates().sort_values('Age').reset_index(drop=True) 11print(df) 12# Age Game Console Combined 13#0 15 PS5 14#1 15 XBox 15#2 15 Wii U 16#3 15 Gameboy 17#4 15 PS2 18#5 16 GameCube 19#6 16 PS4 20#7 16 GameBoy Color 21#8 16 PS5 22#9 16 Xbox360 23#10 17 PS3 24#11 17 PS5 25#12 17 PS4 26#13 17 PS Vita

投稿2022/08/11 11:30

meg_

総合スコア10602

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SnowBallEffect

2022/08/12 05:55

ありがとうございます!うまくいきます!ただ、"]["という記号がセルに入っていて、これもsplitしたいのですが、df = df.applymap(lambda x: x.split(r'][' or r',') if r'][' or r',' in str(x) else x)をやったところ、AttributeError: 'float' object has no attribute 'split'というエラーがでてきました。あと、これもためしてみました。df = df.applymap(lambda x: x.split(r'][,\s'*) if r'][|,\s*' in str(x) else x)。これだとコードは走るのですが、なにもsplitしません。おそらく'][,\s*'という記号を探しているのだと思います。。。。。
guest

0

ベストアンサー

python

1dfx = df.set_index('Age').stack().str.split(r',\s*', expand=True)\ 2 .stack().reset_index(level=[1,2], drop=True).reset_index()\ 3 .rename({0: 'Game Console Combined'}, axis='columns') 4 5print(dfx)
AgeGame Console Combined
15PS5
15XBox
15Wii U
15Gameboy
15PS2
16GameCube
16PS4
16GameBoy Color
16PS5
16Xbox 360
17PS3
17PS5
17PS4
17PS Vita

投稿2022/08/11 12:40

melian

総合スコア19849

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SnowBallEffect

2022/08/12 05:27

返信ありがとうございます。このコード、ほぼすべてうまくいます。ただ、本当のデータはdataframeを足すと中にこういう文字があります:"][" Melianさんのdf.set_index('Age').stack().str.split(r',\s*')では空白でsplitするのですが、"]["まではsplitできないようです。str.split(r',\s*\[\]')と素人なりにやってみますが、それでもだめでした。。"]["さえ、取れればうまくいくのですが。。。。 
melian

2022/08/12 06:23

r',\s*' を r',\s*|\s*\]\[\s*' に変更して試してみてください。
SnowBallEffect

2022/08/12 07:35

すごい!ありがとうございます!完璧です!regexをもう少し勉強します!本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問