[英]How can I transform a list of tuples into a pandas dataframe so that the first value of each tuple represents a column?
[英]How do I join six list of tuples into a pandas dataframe using the first value of each tuple as the key?
我正在測試一個服務,它有一個可以從中提取解析的 10K 公司數據的 api。 對於提取的每個指標(EBIT、現金、總資產等),我將季度日期和指標存儲在一個元組中,並將每個元組存儲在一個列表中。 結果是 43 - 80 個元組的六個列表。 我想要一個包含公司代碼、日期和指標列的數據框。 我如何將我擁有的(元組列表)變成那個?
下面的代碼用於提取數據(這是示例,因此不收費):
import numpy as np
import json
import pandas as pd
content = requests.get(r'https://eodhistoricaldata.com/api/fundamentals/AAPL.US?api_token=OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX')
ebit_list = []
date_list = []
totalassets_list = []
cash_list = []
totalCurrentAssets_list = []
totalCurrentLiabilities_list = []
for i in content.json()['Financials']['Income_Statement']['quarterly']:
try:
ebit_list.append((i, float(content.json()['Financials']['Income_Statement']['quarterly'][i]['ebit'])))
except:
pass
try:
date_list.append(i)
except:
pass
try:
totalassets_list.append((i, float(content.json()['Financials']['Balance_Sheet']['quarterly'][i]['totalAssets'])))
except:
pass
for i in content.json()['Financials']['Balance_Sheet']['quarterly']:
#print(i, float(content.json()['Financials']['Balance_Sheet']['quarterly']['2019-12-28']['totalCurrentLiabilities']))
try:
cash_list.append((i, float(content.json()['Financials']['Balance_Sheet']['quarterly'][i]['cash'])))
except:
pass
try:
totalCurrentAssets_list.append((i, float(content.json()['Financials']['Balance_Sheet']['quarterly'][i]['totalCurrentAssets'])))
except:
pass
try:
totalCurrentLiabilities_list.append((i, float(content.json()['Financials']['Balance_Sheet']['quarterly'][i]['totalCurrentLiabilities'])))
except:
pass
我想要一個包含所有日期的數據框(意味着如果缺少指標,則填充零)和以下列:
date
、 ebit
、 totalassets
、 cash
、 totalCurrentAssets
、 totalCurrentLiabilities
我不確定如何提取每個元組中的元組和值。
您可以使用pandas.Series
中的map
函數將日期與您需要的數據進行匹配。 這將為沒有匹配值的單元格插入NaN
,這將使以后更容易處理丟失的數據。 如果你還想填零,你可以使用fillna
# Create a dataframe using date
df = pd.DataFrame({'date': date_list})
# To avoid the code getting messy in the next steps
stuff = {'ebit': ebit_list, 'totalassets': totalassets_list, 'cash': cash_list, 'totalCurrentAssets': totalCurrentAssets_list, 'totalCurrentLiabilities': totalCurrentLiabilities_list}
for name, values in stuff.items():
value_dict = {t[0]: t[1] for t in values} # t is each tuple in the list
df[name] = df['date'].map(value_dict) # map will match the correct date to the value
# assuming you need the dataframe to be sorted by date
df['date'] = pd.to_datetime(df['date']) # we should use actual numbers instead of date string
df.sort_values('date', inplace=True, ignore_index=True)
# if you want to fill 0s to missing values
# df.fillna(0, inplace=True)
sort_values
ignore_index
參數是為了確保排序后索引不會混亂。 如果你的pandas
版本是舊的,可能會給一個TypeError: sort_values() got an unexpected keyword argument 'ignore_index'
排序時。 如果是這樣,您應該使用以下內容來重置索引
df.sort_values('date', inplace=True)
df.reset_index(inplace=True)
最后這是 df
date ebit totalassets cash totalCurrentAssets totalCurrentLiabilities
0 2000-03-31 NaN 7.007000e+09 NaN NaN 1.853000e+09
1 2000-06-30 NaN 6.932000e+09 NaN NaN 1.873000e+09
2 2000-09-30 NaN 6.803000e+09 NaN NaN 1.933000e+09
3 2000-12-31 0.000000e+00 5.986000e+09 NaN NaN 1.637000e+09
4 2001-03-31 0.000000e+00 6.130000e+09 NaN NaN 1.795000e+09
.. ... ... ... ... ... ...
75 2018-12-29 2.334600e+10 3.737190e+11 4.477100e+10 1.408280e+11 1.082830e+11
76 2019-03-30 1.341500e+10 3.419980e+11 3.798800e+10 1.233460e+11 9.377200e+10
77 2019-06-29 1.154400e+10 3.222390e+11 5.053000e+10 1.349730e+11 8.970400e+10
78 2019-09-28 1.562500e+10 3.385160e+11 4.884400e+10 1.628190e+11 1.057180e+11
79 2019-12-28 2.556900e+10 3.406180e+11 3.977100e+10 1.632310e+11 1.021610e+11
我無法讓您的示例工作,請求未定義。
但這里有一些代碼可以做你想要的:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pandas as pd
def create_df(list_of_lists):
pd.DataFrame({x[0]: pd.Series(x[1:]) for x in list of lists})
我們實際上可以大大簡化此代碼以獲得您想要的結果(並使其在將來更容易調整!)
完成的代碼在這里,下面有更詳細的解釋:
import numpy as np
import json
import pandas as pd
import requests
content = requests.get(r'https://eodhistoricaldata.com/api/fundamentals/AAPL.US?api_token=OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX')
income_data = content.json()['Financials']['Income_Statement']['quarterly']
income = pd.DataFrame.from_dict(income_data).transpose().set_index("date")
income = income[['ebit']]
balance_data = content.json()['Financials']['Balance_Sheet']['quarterly']
balance = pd.DataFrame.from_dict(balance_data).transpose().set_index("date")
balance = balance[['totalAssets', 'cash', 'totalCurrentAssets', 'totalCurrentLiabilities']]
financials = income.merge(balance, left_index = True, right_index = True).fillna(0)
財務數據框將如下所示(僅顯示 2005-2009 年的數據):
| date | ebit | totalAssets | cash | totalCurrentAssets | totalCurrentLiabilities |
|:-----------|----------:|--------------:|-----------:|---------------------:|--------------------------:|
| 2009-12-26 | 4.758e+09 | 5.3926e+10 | 7.609e+09 | 3.3332e+10 | 1.3097e+10 |
| 2009-09-26 | 0 | 4.7501e+10 | 5.263e+09 | 3.1555e+10 | 1.1506e+10 |
| 2009-06-27 | 1.732e+09 | 4.814e+10 | 5.605e+09 | 3.517e+10 | 1.6661e+10 |
| 2009-03-31 | 0 | 4.3237e+10 | 4.466e+09 | 0 | 1.3751e+10 |
| 2008-12-31 | 0 | 4.2787e+10 | 7.236e+09 | 0 | 1.4757e+10 |
| 2008-09-30 | 0 | 3.9572e+10 | 1.1875e+10 | 0 | 1.4092e+10 |
| 2008-06-30 | 0 | 3.1709e+10 | 9.373e+09 | 0 | 9.218e+09 |
| 2008-03-31 | 0 | 3.0471e+10 | 9.07e+09 | 0 | 9.634e+09 |
| 2007-12-31 | 0 | 3.0039e+10 | 9.162e+09 | 0 | 1.0535e+10 |
| 2007-09-30 | 0 | 2.5347e+10 | 9.352e+09 | 0 | 9.299e+09 |
| 2007-06-30 | 0 | 2.1647e+10 | 7.118e+09 | 0 | 6.992e+09 |
| 2007-03-31 | 0 | 1.8711e+10 | 7.095e+09 | 0 | 5.485e+09 |
| 2006-12-31 | 0 | 1.9461e+10 | 7.159e+09 | 0 | 7.337e+09 |
| 2006-09-30 | 0 | 1.7205e+10 | 6.392e+09 | 0 | 6.471e+09 |
| 2006-06-30 | 0 | 1.5114e+10 | 0 | 0 | 5.023e+09 |
| 2006-03-31 | 0 | 1.3911e+10 | 0 | 0 | 4.456e+09 |
| 2005-12-31 | 0 | 1.4181e+10 | 0 | 0 | 5.06e+09 |
| 2005-09-30 | 0 | 1.1551e+10 | 3.491e+09 | 0 | 3.484e+09 |
| 2005-06-30 | 0 | 1.0488e+10 | 0 | 0 | 3.123e+09 |
| 2005-03-31 | 0 | 1.0111e+10 | 0 | 0 | 3.352e+09 |
content.json()['Financials']['Income_Statement']['quarterly']
是一個字典,每個鍵是日期,每個值是帶有列數據的第二個字典。
{'2005-03-31': {'date': '2005-03-31',
'filing_date': None,
'currency_symbol': 'USD',
'researchDevelopment': '120000000.00',
...},
'2005-06-30': {...},
...}
由於是這種情況,您實際上可以通過使用將該字典直接加載到 Pandas 數據幀中
pd.DataFrame.from_dict(income_data).transpose().set_index("date")
由於 JSON 的結構,轉置是必要的。 Pandas 需要一個格式為{'column name': data}
的字典。 由於鍵是日期,您最初將獲得一個 DataFrame,其中行標記為“totalAssets”、“cash”等,列是日期。 transpose()
命令翻轉行和列,使其成為您需要的格式。 最后的.set_index("date")
命令用於使用“日期”數據而不是初始關鍵日期,以保持一致性並命名索引。 它是完全可選的
現在,此 DataFrame 將包含 JSON 文件中的每一列,但您只對其中的幾列感興趣。 編碼
income = income[['ebit']]
僅從數據中選擇相關列。
由於您從兩個不同的來源提取數據,因此您確實需要創建兩個不同的表。 這有一個額外的好處,您可以更清楚地看到哪些列是從“損益表”中提取的,哪些列來自“資產負債表”。
最后一行
financials = income.merge(balance, left_index = True, right_index = True).fillna(0)
使用它們的索引(在本例中為“日期”列)將兩個表合並在一起。 fillna(0)
確保按照您的要求將任何缺失的數據替換為零值。
如果您最終需要添加另一個表,例如“Cash_Flow”,您將使用相同的代碼行來創建表並選擇相關列,然后添加第二個合並行:
cashflow_data = content.json()['Financials']['Balance_Sheet']['quarterly']
cashflow = pd.DataFrame.from_dict(cashflow_data).transpose().set_index("date")
cashflow = cashflow[['accountsPayable', 'liabilitiesAndStockholdersEquity']]
...
financials.merge(cashflow, left_index = True, right_index = True).fillna(0)
作為額外提示,您的源 JSON 中有相當多的數據! 要查看任何給定表中哪些列可供您使用,請使用以下命令:
cashflow.columns.sort_values()
獲取您可以使用的列的按字母順序排列的列表:
['accountsPayable', 'accumulatedAmortization', 'accumulatedDepreciation',
'accumulatedOtherComprehensiveIncome', 'additionalPaidInCapital',
'capitalLeaseObligations', 'capitalSurpluse', 'cash',
'cashAndShortTermInvestments', 'commonStock',
'commonStockSharesOutstanding', 'commonStockTotalEquity',
'currency_symbol', 'deferredLongTermAssetCharges',
'deferredLongTermLiab', 'filing_date', 'goodWill', 'intangibleAssets',
'inventory', 'liabilitiesAndStockholdersEquity', 'longTermDebt',
'longTermDebtTotal', 'longTermInvestments', 'negativeGoodwill',
'netReceivables', 'netTangibleAssets', 'nonCurrentAssetsTotal',
'nonCurrentLiabilitiesOther', 'nonCurrentLiabilitiesTotal',
'nonCurrrentAssetsOther', 'noncontrollingInterestInConsolidatedEntity',
'otherAssets', 'otherCurrentAssets', 'otherCurrentLiab', 'otherLiab',
'otherStockholderEquity', 'preferredStockRedeemable',
'preferredStockTotalEquity', 'propertyPlantAndEquipmentGross',
'propertyPlantEquipment', 'retainedEarnings',
'retainedEarningsTotalEquity', 'shortLongTermDebt', 'shortTermDebt',
'shortTermInvestments',
'temporaryEquityRedeemableNoncontrollingInterests', 'totalAssets',
'totalCurrentAssets', 'totalCurrentLiabilities', 'totalLiab',
'totalPermanentEquity', 'totalStockholderEquity', 'treasuryStock',
'warrants']
當數據中存在拼寫錯誤時,這也非常有用,例如上面的“capitalSurpluse”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.