从数据框中挑选特定值?

时间:2017-08-27 14:26:07

标签: python pandas dictionary dataframe

我有一个我从json url创建的数据框。它有两列,bpi和时间。 bpi值是前三行的字典,时间值是NaN。最后三行是bpi的NaN和时间的timedate值。我想返回第3行,第1列和第4行第2列。复杂的部分是从第3行第1列开始,我想从字典中仅选择特定的键值对。我怎样才能做到这一点?

[in] print(btc)
[out]
                                                          bpi  \
EUR         {'code': 'EUR', 'symbol': '€', 'rate': '3...   
GBP         {'code': 'GBP', 'symbol': '£', 'rate': '...   
USD         {'code': 'USD', 'symbol': '$', 'rate': '4,...   
updated                                                   NaN   
updatedISO                                                NaN   
updateduk                                                 NaN   

                                 time  
EUR                               NaN  
GBP                               NaN  
USD                               NaN  
updated     Aug 27, 2017 14:07:00 UTC  
updatedISO  2017-08-27T14:07:00+00:00  
updateduk   Aug 27, 2017 at 15:07 BST  

我只想要美国字典中的rate加上updated列中的time值。

每个日期值的输出应为一行 - 后跟列出rate

以下是使用pandas .to_dict

修改df时的输出
[in]
btc_dict = btc.to_dict()

print(btc_dict)
[out]
{'bpi': {'EUR': {'code': 'EUR', 'symbol': '€', 'rate': '3,671.8281', 'description': 'Euro', 'rate_float': 3671.8281}, 'GBP': {'code': 'GBP', 'symbol': '£', 'rate': '3,397.8616', 'description': 'British Pound Sterling', 'rate_float': 3397.8616}, 'USD': {'code': 'USD', 'symbol': '$', 'rate': '4,378.8400', 'description': 'United States Dollar', 'rate_float': 4378.84}, 'updated': nan, 'updatedISO': nan, 'updateduk': nan}, 'time': {'EUR': nan, 'GBP': nan, 'USD': nan, 'updated': 'Aug 27, 2017 14:07:00 UTC', 'updatedISO': '2017-08-27T14:07:00+00:00', 'updateduk': 'Aug 27, 2017 at 15:07 BST'}}

2 个答案:

答案 0 :(得分:1)

IIUC,您可以使用df.loc并访问这些值,如下所示:

r = df.loc['USD', 'bpi']['rate']
y = df.loc['updated', 'time']

df = pd.DataFrame({'btc_price (USD)': [r], 'time' : [y]}) 
print(df)

  btc_price (USD)                       time
0      4,378.8400  Aug 27, 2017 14:07:00 UTC

要保存为CSV,您可以使用df.to_csv

df.to_csv('out.csv')

如果您将来必须附加到同一数据框,您首先要创建一个新的数据框并附加到现有的CSV文件中:

df_new = pd.DataFrame([[new_rate, new_time]], columns=['btc_price (USD)', 'time'])
with open('out.csv', 'a') as f:
    df_new.to_csv(f, header=False)

答案 1 :(得分:1)

在我看来,最好是从dict s创建新列:

d = {'bpi': {'EUR': {'code': 'EUR', 'symbol': '€', 'rate': '3,671.8281', 'description': 'Euro', 'rate_float': 3671.8281}, 'GBP': {'code': 'GBP', 'symbol': '£', 'rate': '3,397.8616', 'description': 'British Pound Sterling', 'rate_float': 3397.8616}, 'USD': {'code': 'USD', 'symbol': '$', 'rate': '4,378.8400', 'description': 'United States Dollar', 'rate_float': 4378.84}, 'updated': np.nan, 'updatedISO': np.nan, 'updateduk': np.nan}, 'time': {'EUR': np.nan, 'GBP': np.nan, 'USD': np.nan, 'updated': 'Aug 27, 2017 14:07:00 UTC', 'updatedISO': '2017-08-27T14:07:00+00:00', 'updateduk': 'Aug 27, 2017 at 15:07 BST'}}
df = pd.DataFrame(d)
#replace NaNs to {}
df['bpi'] = df['bpi'].fillna(pd.Series([{}], index=df.index))

#new df by constructor, join column time last
df1 = pd.DataFrame(df['bpi'].values.tolist(), index=df.index).join(df['time'])
#convert rate column to float 
df1['rate'] = df1['rate'].replace(',','',regex=True).astype(float)
#convert time column to datetimes
df1['time'] = pd.to_datetime(df1['time'])
print (df1)
           code             description       rate  rate_float   symbol  \
EUR         EUR                    Euro  3671.8281   3671.8281   €   
GBP         GBP  British Pound Sterling  3397.8616   3397.8616  £   
USD         USD    United States Dollar  4378.8400   4378.8400    $   
updated     NaN                     NaN        NaN         NaN      NaN   
updatedISO  NaN                     NaN        NaN         NaN      NaN   
updateduk   NaN                     NaN        NaN         NaN      NaN   

                          time  
EUR                        NaT  
GBP                        NaT  
USD                        NaT  
updated    2017-08-27 14:07:00  
updatedISO 2017-08-27 14:07:00  
updateduk  2017-08-27 15:07:00  

或者如果可能的话,使用此json_normalize中的solution和原始json数据:

df = json_normalize(d)
print (df)

最后按boolean indexing过滤:

#sample
df3 = df1[(df1['code'] == 'EUR') & (df1['rate'] > 1000)]
print (df3)
    code description       rate  rate_float  symbol time
EUR  EUR        Euro  3671.8281   3671.8281  €  NaT