从熊猫系列中提取“ url”值

时间:2019-04-25 15:24:13

标签: python pandas

我有一个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。 谢谢

3 个答案:

答案 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.Seriesto_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)

我们可以在此处将iterrowslist 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