如何使用Python读取对象列的属性
我有一个数据框,其中'location'列包含一个对象:如何使用Python读取对象列的属性,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有一个数据框,其中'location'列包含一个对象: import pandas as pd item1 = { 'project': 'A', 'location': {'country': 'united states', 'city': 'new york'}, 'raised_usd': 1.0} item2 = { 'project': 'B', 'location': {'country': 'united kingdom',
import pandas as pd
item1 = {
'project': 'A',
'location': {'country': 'united states', 'city': 'new york'},
'raised_usd': 1.0}
item2 = {
'project': 'B',
'location': {'country': 'united kingdom', 'city': 'cambridge'},
'raised_usd': 5.0}
item3 = {
'project': 'C',
'raised_usd': 10.0}
data = [item1, item2, item3]
df = pd.DataFrame(list(data))
df
我想创建一个额外的专栏,'project\u country',其中只包含国家信息(如果可用)。我尝试了以下方法:
def get_country(location):
try:
return location['country']
except Exception:
return 'n/a'
df['project_country'] = get_country(df['location'])
df
但这不起作用:
如何导入此字段?使用并向其传递func:
In [62]:
def get_country(location):
try:
return location['country']
except Exception:
return 'n/a'
df['project_country'] = df['location'].apply(get_country)
df
Out[62]:
location project raised_usd \
0 {'country': 'united states', 'city': 'new york'} A 1
1 {'country': 'united kingdom', 'city': 'cambrid... B 5
2 NaN C 10
project_country
0 united states
1 united kingdom
2 n/a
原始代码失败的原因是传递的是整个列或系列:
In [64]:
def get_country(location):
print(location)
try:
print(location['country'])
except Exception:
print('n/a')
get_country(df['location'])
0 {'country': 'united states', 'city': 'new york'}
1 {'country': 'united kingdom', 'city': 'cambrid...
2 NaN
Name: location, dtype: object
n/a
因此,尝试使用整个系列查找密钥会引发一个
KeyError
,然后返回'n/a'
。EdChum指出的正确方法是在“位置”列上使用apply
。您可以将该代码压缩为一行:
In [15]: df['location'].apply(lambda v: v.get('country') if isinstance(v, dict) else '')
Out[15]:
0 united states
1 united kingdom
2
Name: location, dtype: object
并将其指定给列:
In [16]: df['country'] = df['location'].apply(lambda v: v.get('country') if isinstance(v, dict) else '')
In [17]: df
Out[17]:
location project raised_usd \
0 {u'country': u'united states', u'city': u'new ... A 1
1 {u'country': u'united kingdom', u'city': u'cam... B 5
2 NaN C 10
country
0 united states
1 united kingdom
2
使用
apply
,您可以使用。注意我们需要使用dropna()
,因为您的列包含NaN:
from operator import itemgetter
df['location'].apply(itemgetter('country'))
df['location'].dropna().apply(itemgetter('country'))
0 united states
1 united kingdom
Name: location, dtype: object
另一种方法是使用
.str[]
。它隐式调用\uuuu getitem\uuuu
,每个项都有键
参数:
In [17]: df['location'].str['country']
Out[17]:
0 united states
1 united kingdom
2 NaN
Name: location, dtype: object
如果出现错误,它将返回
NaN
,否则将返回值。严格来说,在Python中,这些是(dict的)项,而不是属性。回到最初的JSON,它们是属性。不幸的是,在最新版本的pandas
中,这似乎不再适用。我得到“AttributeError:只能使用带字符串值的.str访问器!”。@timgeb您使用哪个版本?我现在正在用1.2.1进行测试,它工作正常。