Python 如何通过拆分现有列来创建新列

Python 如何通过拆分现有列来创建新列,python,pandas,Python,Pandas,我有一个熊猫DF,看起来像: Keyword | ranks | search_type | search_volume kw1 |[{'rank': 1, 'url': example.com}]| 1 | 500 kw1 |[{'rank': 1, 'url': example.com}]| 2 | 500 kw2 |[{'rank': 2, 'url': exam

我有一个熊猫DF,看起来像:

Keyword |              ranks              | search_type |   search_volume
kw1     |[{'rank': 1, 'url': example.com}]|  1          |   500
kw1     |[{'rank': 1, 'url': example.com}]|  2          |   500
kw2     |[{'rank': 2, 'url': example.com}]|  1          |   1500
kw2     |[{'rank': 2, 'url': example.com}]|  2          |   1500
kw3     |[{'rank': 1, 'url': example.com}]|  1          |   60
kw3     |[{'rank': 1, 'url': example.com}]|  2          |   60
我想要将列拆分为两列:包含列的列和包含url的名为url的新列,因此生成的df将如下所示:

Keyword |   ranks    |        url          | search_type |   search_volume
kw1     |[{'rank': 1 | 'url': example.com}]|  1          |   500
kw1     |[{'rank': 1 | 'url': example.com}]|  2          |   500
kw2     |[{'rank': 2 | 'url': example.com}]|  1          |   1500
kw2     |[{'rank': 2 | 'url': example.com}]|  2          |   1500
kw3     |[{'rank': 1 | 'url': example.com}]|  1          |   60
kw3     |[{'rank': 1 | 'url': example.com}]|  2          |   60
到目前为止,我已经尝试:

df.ranks=df.ranks.str.split',',1.tolist,它会返回一个NAN列表,我也尝试过df['ranks'].str.split',',expand=True,但不起作用。我试过:

df=pd.DataFramedf.ranks.str.split'',1.tolist,columns=['ranks','url']

但我得到ValueError:传递值的形状是1400,索引意味着返回2400

编辑:df.ranks.dtype返回数据类型“0” typedf.ranks返回pandas.core.series.series

剥离并拆分,扩展参数设置为true,即

df[['rank','url']] = df['ranks'].str.strip('{[]}').str.split(',',expand=True).values

  Keyword                              ranks  search_type  search_volume       rank                  url
0  kw1       [{'rank': 1, 'url': example.com}]            1            500  'rank': 1   'url': example.com
1  kw1       [{'rank': 1, 'url': example.com}]            2            500  'rank': 1   'url': example.com
2  kw2       [{'rank': 2, 'url': example.com}]            1           1500  'rank': 2   'url': example.com
3  kw2       [{'rank': 2, 'url': example.com}]            2           1500  'rank': 2   'url': example.com
4  kw3       [{'rank': 1, 'url': example.com}]            1             60  'rank': 1   'url': example.com
5  kw3       [{'rank': 1, 'url': example.com}]            2             60  'rank': 1   'url': example.com
如果不是,也可以将字符串转换为dict,即

df[['rank','url']] =pd.concat(df['ranks'].apply(literal_eval).apply(pd.io.json.json_normalize).tolist()).values

# df[['rank','url']] =pd.concat(df['ranks'].apply(pd.io.json.json_normalize).tolist()).values # If you have lists with dict 

  Keyword                                ranks  search_type  search_volume  rank          url
0  kw1       [{'rank': 1, 'url': "example.com"}]            1            500     1  example.com
1  kw1       [{'rank': 1, 'url': "example.com"}]            2            500     1  example.com
2  kw2       [{'rank': 2, 'url': "example.com"}]            1           1500     2  example.com
3  kw2       [{'rank': 2, 'url': "example.com"}]            2           1500     2  example.com
4  kw3       [{'rank': 1, 'url': "example.com"}]            1             60     1  example.com
5  kw3       [{'rank': 1, 'url': "example.com"}]            2             60     1  example.com
试试这个

df['ranks'].str.split',',expand=True.renamecolumns={0:'ranks',1:'url}

我认为有带dicts的列表,因此建议使用列表理解,选择列表的第一个字典并按键选择:

或:


哇。求你了,别用那个条子和劈叉。如果您的输入数据是字符串JSON,则不应仅使用:

import json

df['rank'].map(lambda x: json.loads(x)[0]['rank'])
df['url'].map(lambda x: json.loads(x)[0]['url'])

我尝试了这一点,但我得到了这个错误:AttributeError:只能使用带字符串值的.str访问器,它在pandasain中使用np.object\udtype,而不是列组字符串dtype?也许可以尝试使用df['ranks'].astypestr.str…..谢谢。我的完整语句是df[['rank','url']]=df['ranks'].astypestr.str.strip'{[]}.str.split',',expand=True.values,返回KeyError:['rank''url']不在索引中,我不明白它返回的原因。@jceg316尝试做类似于df['rank']=nan'df['url']=nan'的事情,有时,pandas希望列已经存在于DataFrame中。我尝试过这样做,但它返回1x400 df的NaNvalues@jceg316-你要去哪里,南。我不明白。我用相同的代码得到了输出他的等级列不是string@jceg316-如果您的列不是字符串类型,请添加此行,df['ranks']=df['ranks']。astypestr@MohamedALANI-添加到评论中:谢谢,我收到了KeyError:“url”数据的来源是什么?一些json?可能需要第一步df['ranks']=df['ranks'].applyast.literal\u eval或df['ranks']=df['ranks']。astypestr.applyast.literal\u eval它来自API@jceg316-然后建议使用
df['r'] = [x[0]['rank'] for x in df['ranks']]
df['u'] = [x[0]['url'] for x in df['ranks']]
print (df)
  Keyword                                ranks  search_type  search_volume  r  \
0     kw1  [{'rank': 1, 'url': 'example.com'}]            1            500  1   
1     kw1  [{'rank': 1, 'url': 'example.com'}]            2            500  1   
2     kw2  [{'rank': 2, 'url': 'example.com'}]            1           1500  2   
3     kw2  [{'rank': 2, 'url': 'example.com'}]            2           1500  2   
4     kw3  [{'rank': 1, 'url': 'example.com'}]            1             60  1   
5     kw3  [{'rank': 1, 'url': 'example.com'}]            2             60  1   

             u  
0  example.com  
1  example.com  
2  example.com  
3  example.com  
4  example.com  
5  example.com 
df['r'] = [{'rank': x[0]['rank']} for x in df['ranks']]
df['u'] = [{'url': x[0]['url']} for x in df['ranks']]
print (df)
  Keyword                                ranks  search_type  search_volume  \
0     kw1  [{'rank': 1, 'url': 'example.com'}]            1            500   
1     kw1  [{'rank': 1, 'url': 'example.com'}]            2            500   
2     kw2  [{'rank': 2, 'url': 'example.com'}]            1           1500   
3     kw2  [{'rank': 2, 'url': 'example.com'}]            2           1500   
4     kw3  [{'rank': 1, 'url': 'example.com'}]            1             60   
5     kw3  [{'rank': 1, 'url': 'example.com'}]            2             60   

             r                       u  
0  {'rank': 1}  {'url': 'example.com'}  
1  {'rank': 1}  {'url': 'example.com'}  
2  {'rank': 2}  {'url': 'example.com'}  
3  {'rank': 2}  {'url': 'example.com'}  
4  {'rank': 1}  {'url': 'example.com'}  
5  {'rank': 1}  {'url': 'example.com'}  
import json

df['rank'].map(lambda x: json.loads(x)[0]['rank'])
df['url'].map(lambda x: json.loads(x)[0]['url'])