我有一个Pandas DataFrame,其以下列称为“ image_versions2.candidates”:
df_myposts['image_versions2.candidates']
那给我:
0 [{'width': 750, 'height': 498, 'url': 'https:/XXX'}]
1 NaN
2 [{'width': 750, 'height': 498, 'url': 'https:/YYY'}]
3 [{'width': 750, 'height': 498, 'url': 'https:/ZZZ'}]
我正在尝试将网址提取到一个名为“ image_url”的新列中。
我可以使用以下代码提取单个URL:
df_myposts['image_versions2.candidates'][0][0]['url']
'https:/XXX'
但是第二行由于de NaN值而给我以下错误:
df_myposts['image_versions2.candidates'][1][0]['url']
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-64-3f0532195cb7> in <module>
----> 1 df_myposts['image_versions2.candidates'][1][0]['url']
TypeError: 'float' object is not subscriptable
我正在尝试某种类型的循环和if条件,但是我遇到了类似的错误消息:
for i in df_myposts['image_versions2.candidates']:
if type(i[0]) == 'list':
在不删除NaN行的情况下,执行此操作哪个更好? 我还有另一列带有ID的列,因此我想保留关系id <-> url。 谢谢
答案 0 :(得分:3)
使用:
df = pd.DataFrame({'a':[1,2,3], 'b':[[{'width': 750, 'height': 498, 'url': 'https:/XXX'}], [{'width': 750, 'height': 498, 'url': 'https:/YYY'}], None]})
# df.dropna(inplace = True) #drop rows with null values
# to preserve rows with NaN, first replace NaN values with a scalar/dict value
df.fillna('null', inplace=True)
df['c'] = df['b'].apply(lambda x: [y['url'] if isinstance(x, list) else 'null' for y in x])
df['c'] = df['c'].apply(lambda x:x[0]) #get only the url from the list
#Output:
a b c
0 1 [{'width': 750, 'height': 498, 'url': 'https:/... https:/XXX
1 2 [{'width': 750, 'height': 498, 'url': 'https:/... https:/YYY
2 3 null null
答案 1 :(得分:1)
使用@amanb的设置数据框
df = pd.DataFrame({
'a':[1,2,3],
'b':[
[{'width': 750, 'height': 498, 'url': 'https:/XXX'}],
[{'width': 750, 'height': 498, 'url': 'https:/YYY'}],
None
]
})
您可以使用str
的{{1}}访问器来获取列表的第一个元素。然后使用pandas.Series
和to_dict
from_dict
获得
pd.DataFrame.from_dict(df.b.dropna().str[0].to_dict(), orient='index')
您可以使用 width height url
0 750 498 https:/XXX
1 750 498 https:/YYY
添加到join
df
或者您可以替换列
df.join(pd.DataFrame.from_dict(df.b.dropna().str[0].to_dict(), orient='index'))
a b width height url
0 1 [{'width': 750, 'height': 498, 'url': 'https:/... 750.0 498.0 https:/XXX
1 2 [{'width': 750, 'height': 498, 'url': 'https:/... 750.0 498.0 https:/YYY
2 3 None NaN NaN NaN
但是我最喜欢的是使用df.assign(b=pd.DataFrame.from_dict(df.b.dropna().str[0].to_dict(), orient='index').url)
a b
0 1 https:/XXX
1 2 https:/YYY
2 3 NaN
代替字典魔术。
pd.io.json.json_normalize
答案 2 :(得分:0)
我们可以在此处将iterrows
与list comprehension
一起使用来提取URL
标签:
df.fillna('None', inplace=True)
df['image_url'] = [
d['image_versions2.candidates']['url'] if d['image_versions2.candidates'] != 'None' else 'None' for idx, d in df.iterrows()
]
print(df)
image_versions2.candidates image_url
0 {'width': 750, 'height': 498, 'url': 'https:/X... https:/XXX
1 None None
2 {'width': 750, 'height': 498, 'url': 'https:/Y... https:/YYY
3 {'width': 750, 'height': 498, 'url': 'https:/Z... https:/ZZZ