[英]Extract dictionary value from column in data frame
我正在寻找一种优化代码的方法。
我有这种形式的条目数据:
import pandas as pn
a=[{'Feature1': 'aa1','Feature2': 'bb1','Feature3': 'cc2' },
{'Feature1': 'aa2','Feature2': 'bb2' },
{'Feature1': 'aa1','Feature2': 'cc1' }
]
b=['num1','num2','num3']
df= pn.DataFrame({'num':b, 'dic':a })
我想从上面数据框中的“dic”列(如果存在)中的字典中提取元素“Feature3”。 到目前为止我能够解决它但我不知道这是否是最快的方法,它似乎有点过于复杂。
Feature3=[]
for idx, row in df['dic'].iteritems():
l=row.keys()
if 'Feature3' in l:
Feature3.append(row['Feature3'])
else:
Feature3.append(None)
df['Feature3']=Feature3
print df
是否有更好/更快/更简单的方法将此 Feature3 提取到 dataframe 中的单独列?
预先感谢您的帮助。
您可以使用列表理解从数据框中的每一行中提取特征 3,返回一个列表。
feature3 = [d.get('Feature3') for d in df.dic]
如果 'Feature3' 不在dic
,则默认返回 None 。
您甚至不需要熊猫,因为您可以再次使用列表理解从原始字典a
提取特征。
feature3 = [d.get('Feature3') for d in a]
df['Feature3'] = df['dic'].apply(lambda x: x.get('Feature3'))
同意 maxymoo。 考虑更改数据框的格式。
(旁注:pandas 通常作为 pd 导入)
如果你apply
一个Series
,你会得到一个非常好的DataFrame
:
>>> df.dic.apply(pn.Series)
Feature1 Feature2 Feature3
0 aa1 bb1 cc2
1 aa2 bb2 NaN
2 aa1 cc1 NaN
从这一点来看,您可以只使用常规的 Pandas 操作。
我认为您可以首先通过comprehension
创建新的DataFrame
,然后创建新列,例如:
df1 = pd.DataFrame([x for x in df['dic']])
print df1
Feature1 Feature2 Feature3
0 aa1 bb1 cc2
1 aa2 bb2 NaN
2 aa1 cc1 NaN
df['Feature3'] = df1['Feature3']
print df
dic num Feature3
0 {u'Feature2': u'bb1', u'Feature3': u'cc2', u'F... num1 cc2
1 {u'Feature2': u'bb2', u'Feature1': u'aa2'} num2 NaN
2 {u'Feature2': u'cc1', u'Feature1': u'aa1'} num3 NaN
或一行:
df['Feature3'] = pd.DataFrame([x for x in df['dic']])['Feature3']
print df
dic num Feature3
0 {u'Feature2': u'bb1', u'Feature3': u'cc2', u'F... num1 cc2
1 {u'Feature2': u'bb2', u'Feature1': u'aa2'} num2 NaN
2 {u'Feature2': u'cc1', u'Feature1': u'aa1'} num3 NaN
时间:
len(df) = 3
:
In [24]: %timeit pd.DataFrame([x for x in df['dic']])
The slowest run took 4.63 times longer than the fastest. This could mean that an intermediate result is being cached
1000 loops, best of 3: 596 µs per loop
In [25]: %timeit df.dic.apply(pn.Series)
1000 loops, best of 3: 1.43 ms per loop
len(df) = 3000
:
In [27]: %timeit pd.DataFrame([x for x in df['dic']])
100 loops, best of 3: 3.16 ms per loop
In [28]: %timeit df.dic.apply(pn.Series)
1 loops, best of 3: 748 ms per loop
我认为您正在考虑的数据结构略有错误。 最好从一开始就创建以特征为列的数据框; pandas 实际上很聪明,可以默认执行此操作:
In [240]: pd.DataFrame(a)
Out[240]:
Feature1 Feature2 Feature3
0 aa1 bb1 cc2
1 aa2 bb2 NaN
2 aa1 cc1 NaN
然后,您将在单独的步骤中添加“num”列,因为数据处于不同的方向,要么使用
df['num'] = b
或者
df = df.assign(num = b)
(我更喜欢第二种选择,因为它具有更实用的风味)。
df = pd.concat([df, pd.DataFrame(list(df['dic']))], axis=1)
然后对结果做任何你想做的事情,如果在一个地方丢失了一个键,你会在那里得到 NaN。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.