簡體   English   中英

從數據框中的列中提取字典值

[英]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)

(我更喜歡第二種選擇,因為它具有更實用的風味)。

現在有一個矢量方法,您可以使用str訪問器:

df['dic'].str['Feature3']

或者用str.get

df['dic'].get('Feature3')

output:

0     cc2
1    None
2    None
Name: dic, dtype: object

df = pd.concat([df, pd.DataFrame(list(df['dic']))], axis=1)

然后對結果做任何你想做的事情,如果在一個地方丟失了一個鍵,你會在那里得到 NaN。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM