2017-09-26 10 views
2

を使用して行に列をリシェイプ私はにこのデータフレームを再構築したいDFにグループごとパンダ

id name value 
1  abc  10 
1  qwe  23 
1  zxc  12 
2  sdf  10 
2  wed  23 
2  abc  12 
2  mnb  11 

を持っている:私たちはidの3行があることがわかります

id n1 n2 n3 n4 
1 abc qwe zxc 0 
2 sdf wed abc mnb 

= id = 2の場合、1行と4行。 そのため、このような出来事の場合、最後の列n4 = 0を置き換えます。

これは、IDの1-2行によっては、あまりにもありかもしれない、ということが起こりあり、テストデータフレームです。

我々はRでやるようにそれが何かある - dcast。 パンダでどうすればいいですか?

答えて

1

あなたは、最後の列の名前を変更し、新しい列名のグループ当たりのカウントのためにcumcountset_indexを使用してunstackによって再構築することができます

df = (df.set_index(['id', df.groupby('id').cumcount()])['name'] 
     .unstack(fill_value=0) 
     .rename(columns = lambda x: 'n{}'.format(x + 1)) 
     .reset_index()) 
print (df) 
    id n1 n2 n3 n4 
0 1 abc qwe zxc 0 
1 2 sdf wed abc mnb 

DataFrameコンストラクタを持つソリューションが必要であり、元のデータにはNaN値ません:

01: GroupBy.applySeriesコンストラクタと
df1 = df.groupby('id')['name'].apply(list) 
print (df1) 
id 
1   [abc, qwe, zxc] 
2 [sdf, wed, abc, mnb] 
Name: name, dtype: object 

df = (pd.DataFrame(df1.values.tolist(), index=df1.index) 
     .fillna(0) 
     .rename(columns = lambda x: 'n{}'.format(x + 1)) 
     .reset_index()) 
print (df) 
    id n1 n2 n3 n4 
0 1 abc qwe zxc 0 
1 2 sdf wed abc mnb 

とソリューション

df1 = (df.groupby('id')['name'].apply(lambda x: pd.Series(x.values, index=range(1,len(x)+1))) 
     .unstack(fill_value=0) 
     .add_prefix('n') 
     .reset_index()) 
print (df1) 

    id n1 n2 n3 n4 
0 1 abc qwe zxc 0 
1 2 sdf wed abc mnb 
2

おそらくオーバーキル

f, u = pd.factorize(df.id.values) 
b = np.bincount(f) 
n, m = u.size, b.max() 
c = np.arange(f.size) - np.arange(n).repeat(b) * (m - 1) 

v = np.zeros((n, m), dtype=object) 
v[f, c] = df.name.values 

pd.DataFrame(
    v, pd.Index(u, name='id'), 
    ['n{}'.format(i) for i in range(1, m + 1)] 
).reset_index() 

    id n1 n2 n3 n4 
0 1 abc qwe zxc 0 
1 2 sdf wed abc mnb 
2

あなたはstrルートを行くとgroupby後、いくつかの正規表現の交換や分割を使用することができます。 Rのdcastのように行うことが可能ですdfplyパッケージを使用することにより

df.groupby('id').name.apply(lambda x: str(list(x)))\ 
      .str.replace("[\[\],']", "")\ 
      .str.split(expand=True).fillna(0)\ 
      .rename(columns = lambda x: 'n{}'.format(x + 1)) 

    n1 n2 n3 n4 
id      
1 abc qwe zxc 0 
2 sdf wed abc mnb 
1

# for Python3 only 
pip install dfply 

dfplyspread機能を使用してください。

import pandas as pd 
from io import StringIO 
from dfply import * 

csv = StringIO("""id,name,value 
1,abc,10 
1,qwe,23 
1,zxc,12 
2,sdf,10 
2,wed,23 
2,abc,12 
2,mnb,11""") 
df = pd.read_csv(csv) 

df['sequence'] = df.groupby('id').cumcount() 
df = df[["id", "sequence", "name"]] >> spread(X.sequence, X.name) 
df = df.set_index("id").fillna(0).rename(columns = lambda x: 'n{}'.format(x + 1)).reset_index() 
print(df) 
# id n1 n2 n3 n4 
# 0 1 abc qwe zxc 0 
# 1 2 sdf wed abc mnb 
関連する問題