如何在熊猫中将一列分为三列

时间:2019-08-21 09:01:30

标签: pandas

我有一个如下所示的数据框

ID  Name     Address
1   Kohli    Country: India; State: Delhi; Sector: SE25
2   Sachin   Country: India; State: Mumbai; Sector: SE39
3   Ponting  Country: Australia; State: Tasmania 
4   Ponting  State: Tasmania; Sector: SE27

从上面我想在下面的数据框里准备

ID  Name     Country   State     Sector
1   Kohli    India     Delhi     SE25
2   Sachin   India     Mumbai    SE39
3   Ponting  Australia Tasmania  None
4   Ponting  None      Tasmania  SE27

我尝试了以下代码

df[['Country', 'State', 'Sector']] = pd.DataFrame(df['ADDRESS'].str.split(';',2).tolist(),
                                   columns = ['Country', 'State', 'Sector'])

但是从上面再次,我必须通过对列进行切片来清理数据。我想知道有没有比这更简单的方法。

3 个答案:

答案 0 :(得分:4)

将列表理解和dict理解用于字典列表,并传递给DataFrame构造函数:

L = [{k:v for y in x.split('; ')  for k, v in dict([y.split(': ')]).items()} 
          for x in df.pop('Address')]

df = df.join(pd.DataFrame(L, index=df.index))
print (df)
   ID     Name    Country     State Sector
0   1    Kohli      India     Delhi   SE25
1   2   Sachin      India    Mumbai   SE39
2   3  Ponting  Australia  Tasmania    NaN

或将split与重塑stack一起使用:

df1 = (df.pop('Address')
         .str.split('; ', expand=True)
         .stack()
         .reset_index(level=1, drop=True)
         .str.split(': ', expand=True)
         .set_index(0, append=True)[1]
         .unstack()
         )
print (df1)
0    Country Sector     State
0      India   SE25     Delhi
1      India   SE39    Mumbai
2  Australia    NaN  Tasmania

df = df.join(df1)
print (df)
   ID     Name    Country Sector     State
0   1    Kohli      India   SE25     Delhi
1   2   Sachin      India   SE39    Mumbai
2   3  Ponting  Australia    NaN  Tasmania

答案 1 :(得分:2)

你快到了

cols = ['ZONE', 'State', 'Sector']
df[cols] = pd.DataFrame(df['ADDRESS'].str.split('; ',2).tolist(),
                                   columns = cols)

for col in cols:
    df[col] = df[col].str.split(': ').apply(lambda x:x[1])

答案 2 :(得分:1)

原始答案

这也可以做到:

import pandas as pd

df = pd.DataFrame(
 [
     {'ID': 1, 'Name': 'Kohli', 'Address': 'Country: India; State: Delhi; Sector: SE25'},
     {'ID': 2, 'Name': 'Sachin','Address': 'Country: India; State: Mumbai; Sector: SE39'},
     {'ID': 3,'Name': 'Ponting','Address': 'Country: Australia; State: Tasmania'}
 ]
)

cols_to_extract = ['ZONE', 'State', 'Sector']
list_of_rows = df['Address'].str.split(';', 2).tolist()
df[cols_to_extract] = pd.DataFrame(
    [[item.split(': ')[1] for item in row] for row in list_of_rows], 
    columns=cols_to_extract)

输出如下:

>> df[['ID', 'Name', 'ZONE', 'State', 'Sector']]

ID  Name    ZONE       State     Sector
1   Kohli   India      Delhi     SE25
2   Sachin  India      Mumbai    SE39
3   Ponting Australia  Tasmania  None

修改后的答案

正如@jezrael在question comment中很好地指出的那样,我的原始答案是错误的,因为当某些值是NaN时,它按位置对齐值并且可能会使用错误的键值对。 s。以下代码应适用于已编辑的数据集。

import pandas as pd

df = pd.DataFrame(
 [
     {'ID': 1, 'Name': 'Kohli', 'Address': 'Country: India; State: Delhi; Sector: SE25'},
     {'ID': 2, 'Name': 'Sachin','Address': 'Country: India; State: Mumbai; Sector: SE39'},
     {'ID': 3,'Name': 'Ponting','Address': 'Country: Australia; State: Tasmania'},
     {'ID': 4, 'Name': 'Ponting','Address': 'State: Tasmania; Sector: SE27'}
 ]
)

cols_to_extract = ['Country', 'State', 'Sector']
list_of_rows = df['Address'].str.split(';', 2).tolist()
df[cols_to_extract] = pd.DataFrame(
    [{item.split(': ')[0].strip(): item.split(': ')[1] for item in row} for row in list_of_rows], 
    columns=cols_to_extract)
df = df.rename(columns={'Country': 'ZONE'})

输出为:

>> df[['ID', 'Name', 'ZONE', 'State', 'Sector']]

ID  Name    ZONE       State     Sector
1   Kohli   India      Delhi     SE25
2   Sachin  India      Mumbai    SE39
3   Ponting Australia  Tasmania  NaN
3   Ponting NaN        Tasmania  SE27