2017-09-28 6 views
0

カラムのセルに複数の値があり、 ';'で区切られたpandasデータフレームがあります。私は、複数の値を(1つのセルで)分割し、分割された値の新しい行を作成しようとしています。以下の例のような何か:Python(Jupyter Notebook):インデックスのエラーの長さに一致しないデータフレームインデックスをコピーするパンダ

> In: df 
> Out: 
| Year | State | Ingredient | Species | 
| 1998 | CA | egg; pork | sp1;sp2 | 

私はこのようなルックスを実現しようとしています結果:

> In: df 
> Out: 
| Year | State | Ingredient | Species | 
| 1998 | CA | egg  | sp1  | 
| 1998 | CA | egg  | sp1  | 
| 1998 | CA | pork  | sp2  | 
| 1998 | CA | pork  | sp2  | 

私はこのようなデータフレームを分割する方法を発見したが、それは一度だけ動作します。私が使用するコードを以下に示す:

sp = df['Species'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
i = sp.index.get_level_values(0) 
df1 = df.loc[i].copy() 
df1['Species] = sp.values 

Iは、元のデータフレーム(DF)を使用して、最初の「種」カラムでこれを実行すると、それが動作します。

しかし、df1でこのコードをもう一度実行して 'Ingredient'を分割しようとすると、の値の長さがインデックスの長さと一致しないというエラーが表示されます。以下に示すよう:

fd = df1['Ingredient'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
j = fd.index.get_level_values(0) 
df2 = df1.loc[j].copy() 
df2['Ingredient'] = fd.values 

私はそれは私にそのエラーメッセージを返す理由を見つけるために、多くの臨床試験をした、と私は、実行時にこれがDF2、それダブルス行の数を作成するために、DF1に再び呼び出さことに気づきました/ indexを実行したときdf2 = df1.loc [j] .copy()。したがって、私に必要以上に多くの行を与えてください。しかし、 'df1'を 'df'(元のデータフレーム)に置き換えた場合、このエラーは表示されず、動作します。

解決方法はありますか?あるいはそれを分割する他の方法はありますか?

ありがとうございます。

ps。これは私の初めてのStack Overflowへの投稿です。私はPythonも新しくなっています。フォーマットが悪い場合は申し訳ありません。

答えて

1

私はあなたの問題を試してみました。あなたのアプローチでは問題を解決できませんでした。あなたは期待された出力を提供して以来、私は別のアプローチを考え出すことができました。うまくいけば、これは簡潔であり、あなたの問題を解決します。

df = pd.DataFrame(columns=['Year', 'State', 'Ingredient', 'Species']) 
df.loc[0] = [1998, 'CA', 'egg; pork', 'sp1;sp2'] # Same input df as problem 
print df 
sp = df['Species'][0].split(';') # Separating by species 
df = pd.concat([df]*len(sp), ignore_index=True) # Add len(sp) more rows 
df['Species'] = sp 
ing = df['Ingredient'][0].split(';') 
df = pd.concat([df]*len(ing), ignore_index=True) 
df['Ingredient'] = ing*len(sp) # Replicate ingredient len(sp) number of times 
print df 
    Year State Ingredient Species 
0 1998 CA egg; pork sp1;sp2 
    Year State Ingredient Species 
0 1998 CA  egg  sp1 
1 1998 CA  pork  sp2 
2 1998 CA  egg  sp1 
3 1998 CA  pork  sp2 

PS:これは答える私の初めてです...私は詳細やフォーマットを追加するには、この答えに変更を加える必要があるなら、私に知らせてください。ありがとう!

編集:あなたのアプローチで何がうまくいかないかを知ることができました。データフレームのコピーを作成するときにインデックスをリセットする必要があります。それ以外の場合は、値0のインデックスを取得すると、現在0であるため複数の値を取得します。

sp = df['Species'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
i = sp.index.get_level_values(0) 
df1 = df.loc[i].copy() 
print df1 
fd = df1['Ingredient'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
j = fd.index.get_level_values(0) 
print j 

df1 = df.loc[i].copy().reset_index(drop=True) 
print df1 
fd = df1['Ingredient'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
j = fd.index.get_level_values(0) 
print j 

出力:

Year State Ingredient Species 
0 1998 CA egg; pork sp1;sp2 
0 1998 CA egg; pork sp1;sp2 
Int64Index([0, 0, 0, 0], dtype='int64') 
    Year State Ingredient Species 
0 1998 CA egg; pork sp1;sp2 
1 1998 CA egg; pork sp1;sp2 
Int64Index([0, 0, 1, 1], dtype='int64') 

修正してオリジナルコード:

df = pd.DataFrame(columns=['Year', 'State', 'Ingredient', 'Species']) 
df.loc[0] = [1998, 'CA', 'egg; pork', 'sp1;sp2'] 
#print df 

sp = df['Species'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
i = sp.index.get_level_values(0) 
df1 = df.loc[i].copy().reset_index(drop=True, inplace=False) 
df1['Species'] = sp.values 


fd = df1['Ingredient'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
j = fd.index.get_level_values(0) 
df2 = df1.loc[j].copy().reset_index(drop=True, inplace=False) 
df2['Ingredient'] = fd.values 
print df2 

希望に役立ちます!

+0

お返事ありがとうございます!あなたのコードを試してみましたが、うまく動作しませんでした。私はデータセットが小さかったので、あなたの方法はあなたのために働いたと思います。私は大規模で複雑なデータセットを持っているので、それが私のためにはうまくいかなかったのです。私の思考過程を本当に助けてくれた「編集」アドバイスをありがとう。私はあなたの方法から多くを学んだ。私が解決策を見つけたら、私はあなたに知らせるでしょう! – Dahlia

+0

元のコードの修正は機能しますか?以前はそれが不適切な機能の問題だったと私は理解していますが、今はパフォーマンスに関する問題ですか? –

+0

素晴らしい、幸運! –

0

上記のvkの「修正済みのオリジナルコード」の助けを借りて。これは、 "値の長さがインデックスの長さと一致しない"というエラーを解決するのに役立ちました。解決策は次のとおりです。reset_index()をコードの適切な場所に配置する必要がありました。

オリジナルコード:

## Separate multiple entries in cells in 'Species' column to new rows: 
sp = df['Species'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
i = sp.index.get_level_values(0) 
df1 = df.loc[i].copy() 
df1['Species] = sp.values 

## Separate multiple entries in cells in 'Ingredient' column to new rows: 
ing = df1['Ingredient'].str.split(';', expand=True).stack().reset_index(level=1, drop=True) 
df2 = df1.loc[j].copy() 
df2['Ingredient'] = ing.values 

固定コード:

## Separate multiple entries in 'Species' column cell into rows 
sp = df['Species'].str.split(';', expand=True).stack() 
i = sp.index.get_level_values(0) 
df1 = df.loc[i].copy().reset_index() 
df1['Species'] = sp.values 

del df1['index'] ## a column called "index" is generated when you execute reset_index() 

## Separate multiple entries in 'Ingredient' column cell into rows: 
ing = df1['Ingredient'].str.split(';', expand=True).stack() 
j = ing.index.get_level_values(0) 
df2 = df1.loc[j].copy() 
df2['Ingredient'] = ing.values 

そして私は、私は '固定コード' で欲しかった出力を得ました。

関連する問題