Python 如何通过拆分现有列来创建新列
我有一个熊猫DF,看起来像: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
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'])