Pandas:根据值将包含分号的列分隔为多个列

kin*_*ing 4 python csv dataframe pandas

我在ddata.csv中的数据如下:

col1,col2,col3,col4
A,10,a;b;c, 20
B,30,d;a;b,40
C,50,g;h;a,60
Run Code Online (Sandbox Code Playgroud)

我想将col3分成多个列,但要基于它们的值。在其他方面,我希望最终数据看起来像

col1, col2, name_a, name_b, name_c, name_d, name_g, name_h, col4
A,    10,   a,      b,      c,      NULL,   NULL,   NULL,   20
B,    30,   a,      b,      NULL,   d,      NULL,   NULL,   40
C,    50,   a,      NULL,   NULL,   NULL,   g,      h,      60
Run Code Online (Sandbox Code Playgroud)

从此答案中获取参考的当前代码不完整:

import pandas as pd

import string
L = list(string.ascii_lowercase)

names = dict(zip(range(len(L)), ['name_' + x for x in  L]))
df = pd.read_csv('ddata.csv')
df2 = df['col3'].str.split(';', expand=True).rename(columns=names)
Run Code Online (Sandbox Code Playgroud)

列名'a','b','c'...是随机抽取的,与实际数据a,b,c不相关。

现在,我的代码可以将“ col3”分为三列,如下所示:

name_a name_b name_c
a      b      c
d      e      f
g      h      i
Run Code Online (Sandbox Code Playgroud)

但是,它应该类似于name_a,name_b,name_c,name_d,name_g,name_h a,b,c,NULL,NULL,NULL a,b,NULL,d,NULL,NULL a,NULL,NULL,NULL,g,h

最后,我只需要用这些多列替换col3。

jez*_*ael 5

用途Series.str.get_dummies

print (df['col3'].str.get_dummies(';'))
   a  b  c  d  g  h
0  1  1  1  0  0  0
1  1  1  0  1  0  0
2  1  0  0  0  1  1
Run Code Online (Sandbox Code Playgroud)

col3要从原始用途中提取列,请使用numpy中的列名称通过多个值DataFrame.pop创建new ,并用和DataFrame替换NaNs的空字符串作为新列名称。DataFrame.whereDataFrame.add_prefix

pos = df.columns.get_loc('col3')

df2 = df.pop('col3').str.get_dummies(';').astype(bool)
df2 = (pd.DataFrame(df2.values * df2.columns.values[ None, :], 
                    columns=df2.columns,
                    index=df2.index)
         .where(df2)
         .add_prefix('name_'))
Run Code Online (Sandbox Code Playgroud)

最后将按位置过滤的所有DataFrame联接iloc在一起,联接方式为concat

df = pd.concat([df.iloc[:, :pos], df2, df.iloc[:, pos:]], axis=1)
print (df)
  col1  col2 name_a name_b name_c name_d name_g name_h  col4
0    A    10      a      b      c    NaN    NaN    NaN    20
1    B    30      a      b    NaN      d    NaN    NaN    40
2    C    50      a    NaN    NaN    NaN      g      h    60
Run Code Online (Sandbox Code Playgroud)