拆分单元格值并将它们放入不同的列表中

Split cells values and put them into different lists

我有一个数据框,在其中一列中,一些单元格包含一个值,而其他单元格包含两个值,依此类推。这些值以“-”分隔。我想获取每个值,具体取决于它在单元格中的位置,并将其放入列表中。

例如:

import pandas as pd
  
df = pd.DataFrame()
  
print(df)
  
df['Name'] = ['Sam', 'Sam-Joe-Ron-Tania', 'Robert-Sam', 'Jack-Daniel-Sam-Joe-Billy-Robert','Billa']
df['IQ'] = [120, 100, 90, 80, 110]
df['Scores'] = [80, 75, 100, 77, 100]

df

我想分开名字,例如,第一个列表只包含名字:['Sam', 'Sam', 'Robert', 'Jack', 'Billa']

第二个列表将按顺序包含第二个名字:['Joe', 'Sam', 'Daniel']

我该怎么做?谢谢!

新专栏

使用正则表达式 str.extract:

df[['First', 'Second']] = df['Name'].str.extract('([^-]+)(?:-([^-]+))?')

str.split 的子集(如果要提取的名称超过 2 个,split 会很有趣,否则更喜欢 extract,这样效率会更高):

N = 2 # number of names to extract
# adapt the assignment below to the number of columns
df[['First', 'Second']] = df['Name'].str.split('-', expand=True, n=N)[range(N)]

输出:

                               Name   IQ  Scores   First  Second
0                               Sam  120      80     Sam     NaN
1                 Sam-Joe-Ron-Tania  100      75     Sam     Joe
2                        Robert-Sam   90     100  Robert     Sam
3  Jack-Daniel-Sam-Joe-Billy-Robert   80      77    Jack  Daniel
4                             Billa  110     100   Billa     NaN

python 列出

如果你真的想要列表:

d = df['Name'].str.extract('([^-]+)(?:-([^-]+))?')

l1 = d[0].dropna().to_list()
# ['Sam', 'Sam', 'Robert', 'Jack', 'Billa']

l2 = d[1].dropna().to_list()
# ['Joe', 'Sam', 'Daniel']

或者在一个命令中:

l1, l2 = (df['Name'].str.extract('([^-]+)(?:-([^-]+))?')
          .apply(lambda s: s.dropna().to_list())
         )

Name 拆分列生成嵌套列表的解决方案 Series.str.split:

L = [[y for y in x if pd.notna(y)] for x in 
                      df['Name'].str.split('-', expand=True).to_numpy().T]

L = df['Name'].str.split('-', expand=True).stack().groupby(level=1).agg(list).tolist()

L = [v.dropna().tolist() for k, v in 
         df['Name'].str.split('-', expand=True).to_dict('series').items()]

print (L)
[['Sam', 'Sam', 'Robert', 'Jack', 'Billa'], 
 ['Joe', 'Sam', 'Daniel'], 
 ['Ron', 'Sam'], 
 ['Tania', 'Joe'], 
 ['Billy'], 
 ['Robert']]

对于 select 使用索引:

print (L[0])
['Sam', 'Sam', 'Robert', 'Jack', 'Billa']

print (L[1])
['Joe', 'Sam', 'Daniel']

print (L[2])
['Ron', 'Sam']
    

详情:

df1 = df['Name'].str.split('-', expand=True)
print (df1)
        0       1     2      3      4       5
0     Sam    None  None   None   None    None
1     Sam     Joe   Ron  Tania   None    None
2  Robert     Sam  None   None   None    None
3    Jack  Daniel   Sam    Joe  Billy  Robert
4   Billa    None  None   None   None    None

对于新列:

df = df.join(df['Name'].str.split('-', expand=True).add_prefix('names'))
print (df)
                               Name   IQ  Scores  names0  names1 names2  \
0                               Sam  120      80     Sam    None   None   
1                 Sam-Joe-Ron-Tania  100      75     Sam     Joe    Ron   
2                        Robert-Sam   90     100  Robert     Sam   None   
3  Jack-Daniel-Sam-Joe-Billy-Robert   80      77    Jack  Daniel    Sam   
4                             Billa  110     100   Billa    None   None   

  names3 names4  names5  
0   None   None    None  
1  Tania   None    None  
2   None   None    None  
3    Joe  Billy  Robert  
4   None   None    None