拆分单元格值并将它们放入不同的列表中
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
我有一个数据框,在其中一列中,一些单元格包含一个值,而其他单元格包含两个值,依此类推。这些值以“-”分隔。我想获取每个值,具体取决于它在单元格中的位置,并将其放入列表中。
例如:
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