python - pandas добавляют данные
Я пытаюсь объединить три отдельных кадра данных (bs_df, дохода_df, cash_df) каждого тикера, а затем добавить их в кадр данных df. Он успешно добавляет фрейм данных в первый раз, когда проходит цикл for, но когда он пытается добавить новый фрейм данных к исходному фрейму данных, он не делает этого и выдает ошибку подтверждения. Я думаю, это потому, что у фреймов данных есть разные столбцы ( ссылка), но я не могу найти способ обойти это и все же создать фрейм данных со всеми именами столбцов и заполнить значениями NaN, если у фрейма данных нет значения для определенного столбец, который имеет другой фрейм данных.
Вот код, который я запускаю:
from yahoofinancials import YahooFinancials
import pandas as pd
tickers = ["PIH","AAPL","AMZN"]
df = pd.DataFrame()
for ticker in tickers:
print (ticker)
# Updates every loop
ticker_yahoo_financials = YahooFinancials(ticker)
# Get financial info
bs_hist = ticker_yahoo_financials.get_financial_stmts('annual', 'balance')
income_hist = ticker_yahoo_financials.get_financial_stmts('annual', 'income')
cash_hist = ticker_yahoo_financials.get_financial_stmts('annual', 'cash')
# Create dataframes and comebine them
bs_df = pd.DataFrame(list(bs_hist['balanceSheetHistory'][ticker][0].values()))
income_df = pd.DataFrame(list(income_hist['incomeStatementHistory'][ticker][0].values()))
cash_df = pd.DataFrame(list(cash_hist['cashflowStatementHistory'][ticker][0].values()))
comb = pd.concat([bs_df, income_df, cash_df], axis=1)
df = df.append(comb)
Вот сообщение об ошибке:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-23-f476ca9fbb70> in <module>()
19 cash_df = pd.DataFrame(list(cash_hist['cashflowStatementHistory'][ticker][0].values()))
20 comb = pd.concat([bs_df, income_df, cash_df], axis=1)
---> 21 df = df.append(comb)
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\frame.py in append(self, other, ignore_index, verify_integrity)
5192 to_concat = [self, other]
5193 return concat(to_concat, ignore_index=ignore_index,
-> 5194 verify_integrity=verify_integrity)
5195
5196 def join(self, other, on=None, how='left', lsuffix='', rsuffix='',
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\reshape\concat.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, copy)
211 verify_integrity=verify_integrity,
212 copy=copy)
--> 213 return op.get_result()
214
215
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\reshape\concat.py in get_result(self)
406 new_data = concatenate_block_managers(
407 mgrs_indexers, self.new_axes, concat_axis=self.axis,
--> 408 copy=self.copy)
409 if not self.copy:
410 new_data._consolidate_inplace()
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\internals.py in concatenate_block_managers(mgrs_indexers, axes, concat_axis, copy)
5205 blocks.append(b)
5206
-> 5207 return BlockManager(blocks, axes)
5208
5209
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\internals.py in __init__(self, blocks, axes, do_integrity_check, fastpath)
3031
3032 if do_integrity_check:
-> 3033 self._verify_integrity()
3034
3035 self._consolidate_check()
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\internals.py in _verify_integrity(self)
3247 'block items\n# manager items: {0}, # '
3248 'tot_items: {1}'.format(
-> 3249 len(self.items), tot_items))
3250
3251 def apply(self, f, axes=None, filter=None, do_integrity_check=False,
AssertionError: Number of manager items must equal union of block items
# manager items: 67, # tot_items: 68
2 ответа
Проблема после concat
Dataframe
S в цикле дублируются index
строки, так что наконец concat
поднять ошибку:
PIH
2017-12-31 2016-12-31 2015-12-31
netIncome 294000.0 11000.0 -1673000.0
netIncome 294000.0 11000.0 -1673000.0
AAPL
2017-09-30 2016-09-24 2015-09-26
netIncome 4.835100e+10 4.568700e+10 5.339400e+10
netIncome 4.835100e+10 4.568700e+10 5.339400e+10
AMZN
2017-12-31 2016-12-31 2015-12-31
netIncome 3.033000e+09 2.371000e+09 596000000.0
netIncome 3.033000e+09 2.371000e+09 596000000.0
Мое решение:
tickers = ["PIH","AAPL","AMZN"]
dfs = []
for t in tickers:
print (t)
# Updates every loop
ticker_yahoo_financials = YahooFinancials(t)
# Get financial info
bs_hist = ticker_yahoo_financials.get_financial_stmts('annual', 'balance')
bs_hist = bs_hist['balanceSheetHistory']
income_hist = ticker_yahoo_financials.get_financial_stmts('annual', 'income')
income_hist = income_hist['incomeStatementHistory']
cash_hist = ticker_yahoo_financials.get_financial_stmts('annual', 'cash')
cash_hist = cash_hist['cashflowStatementHistory']
bs_df = pd.concat([pd.DataFrame(x) for x in bs_hist[t]], axis=1)
income_df = pd.concat([pd.DataFrame(x) for x in income_hist[t]], axis=1)
cash_df = pd.concat([pd.DataFrame(x) for x in cash_hist[t]], axis=1)
comb = pd.concat([bs_df, income_df, cash_df])
#check duplicated index
print (comb[comb.index.duplicated(keep=False)])
#remove duplicated rows(because same)
comb = comb[~comb.index.duplicated()]
dfs.append(comb)
df = pd.concat(dfs, keys=tickers, axis=1)
print (df.head())
PIH AAPL \
2017-12-31 2016-12-31 2015-12-31 2017-09-30
accountsPayable 9805000.0 7294000.0 5146000.0 7.479300e+10
capitalExpenditures -28000.0 -83000.0 -48000.0 -1.245100e+10
capitalSurplus 47064000.0 46809000.0 48688000.0 NaN
cash 23575000.0 43045000.0 47957000.0 2.028900e+10
changeInCash -19470000.0 -4912000.0 -5682000.0 -1.950000e+08
AMZN \
2016-09-24 2015-09-26 2017-12-31 2016-12-31
accountsPayable 5.932100e+10 6.067100e+10 5.278600e+10 3.904800e+10
capitalExpenditures -1.273400e+10 -1.124700e+10 -1.195500e+10 -7.804000e+09
capitalSurplus NaN NaN 2.138900e+10 1.718600e+10
cash 2.048400e+10 2.112000e+10 2.052200e+10 1.933400e+10
changeInCash -6.360000e+08 7.276000e+09 1.188000e+09 3.444000e+09
2015-12-31
accountsPayable 3.076900e+10
capitalExpenditures -5.387000e+09
capitalSurplus 1.339400e+10
cash 1.589000e+10
changeInCash 1.333000e+09
В моём решении получаем Multiindex
в столбцах, поэтому для выбора значений можно использовать xs
или слайсеры:
print (df.xs('PIH', axis=1).head())
2017-12-31 2016-12-31 2015-12-31
accountsPayable 9805000.0 7294000.0 5146000.0
capitalExpenditures -28000.0 -83000.0 -48000.0
capitalSurplus 47064000.0 46809000.0 48688000.0
cash 23575000.0 43045000.0 47957000.0
changeInCash -19470000.0 -4912000.0 -5682000.0
idx = pd.IndexSlice
print (df.loc['accountsPayable', idx['PIH', ['2017-12-31', '2016-12-31']]])
PIH 2017-12-31 9805000.0
2016-12-31 7294000.0
Name: accountsPayable, dtype: float64
print (df.loc['accountsPayable', idx['PIH', '2016-12-31']])
7294000.0