簡體   English   中英

如何從時間序列數據中 select 前 n 列,而不是在 pandas 中使用 nlargest?

[英]How to select top n columns from time series data instead of using nlargest in pandas?

我有基於每周的貿易出口時間序列數據,我需要制作一個堆疊條 plot 以可視化貿易活動。 為此,我匯總了我的數據以匯總所有行的每列,然后使用nlargest()到 select 前 n 列。 但是,這樣做可能不太准確,因為我為循環中的不同年份制作了堆疊的 plot,並且每年的前 n 列可能不同。 但是我所做的是,取所有行(也就是包括所有年份)的每一列的總和,然后取 select top n 列,這是有偏差的。 所以,我正在研究這樣做的不同方式,也許我可以按每年對時間序列數據進行分組,然后制作堆疊的 plot。 是否有其他方法可以從時間序列數據中選擇前 n 列而不是使用nlargest 有誰知道這樣做的任何可能的方法? 我們還有什么其他方法可以 select 從時間序列數據中排名前 n 列? 任何想法?

我目前的嘗試

這是我目前操縱時間序列數據的嘗試,我在其中聚合所有行的每一列,然后使用nlargest() select top n 列:

import pandas as pd

# load the data
url = 'https://gist.githubusercontent.com/adamFlyn/a6048e547b5a963c7af356c964d15af6/raw/c57c7915cf14f81edc9d5eadaf14efbd43d3e58a/trade_df.csv'
df_ = pd.read_csv(url, parse_dates=['weekly'])
df_.set_index('weekly', inplace=True)
df_.loc['Total',:]= df_.sum(axis=0)
df1 = df_.T
df1 =df1.nlargest(6, columns=['Total'])
df1.drop('Total', axis=1, inplace=True)
df2 = df1.T
df2.reset_index(inplace=True)
df2['weekly'] = pd.to_datetime(df2['weekly'])
df2['year'] = df2['weekly'].dt.year
df2['week'] = df2['weekly'].dt.strftime('%W').astype('int')

然后我用matplotlib可視化繪圖數據,如下所示:

import matplotlib.pyplot as plt

plt_df = df2.set_index(['year','week'])
plt_df.drop("weekly", axis=1, inplace=True)
for n, g in plt_df.groupby(level=0):
    ax = g.loc[n].plot.bar(stacked=True, title=f'{n} Year', figsize=(8,5))
    plt.show()

雖然目前堆疊 plot 的方法的output 很好,但是使用nlargest()選擇前 n 列並不十分准確。例如,在 2019 年美國農業部的報告中,中國不是美國的最大貿易伙伴,但在 2020 年末,中國從美國獲得更多產品,如果我使用nlargest()到 select 頂欄(或貿易伙伴),這將是有問題的,中國不會在列表中,也不會在 plot 中。

更新

正如@Vaishali 在這篇文章的評論中所建議的那樣,使用head()提取頂部列可能是個好主意,所以我嘗試這樣:

for n, g in plt_df.groupby(level=0):
    for i in g:
        gg = g[i].sort_values(g[i].values,ascending = False).groupby('week').head(5)
        ax = gg.loc[n].plot.bar(stacked=True, title=f'{n} Year', figsize=(8,5))

但這不起作用。 誰能指出我如何從時間序列數據中獲得 select top n 列? 任何想法?

我不確定我是否正確理解了這里的要求,但這是基於您的 output 圖表:

使用 sum 和 nlargest filter df by top_countries 查找前 n 個國家,groupby 年份和周,每個唯一年份的 sum,plot 堆疊圖

df.columns = df.columns.str.strip()
top_countries = df.iloc[:, 1:].sum().nlargest(6).index.tolist()
df['weekly'] = pd.to_datetime(df['weekly'])
agg = df[top_countries].groupby([df['weekly'].dt.year.rename('year'),df['weekly'].dt.week.rename('week')]).sum()
for year in df['weekly'].dt.year.unique():
    agg[agg.index.get_level_values(0) == year].droplevel(level=0).plot.bar(stacked = True, figsize = (10,5), title = year)

在此處輸入圖像描述

在此處輸入圖像描述

在此處輸入圖像描述

編輯:如果您想按年份過濾頂級國家/地區,請將您過濾 df 的部分移動到循環中,

df.columns = df.columns.str.strip()
df['weekly'] = pd.to_datetime(df['weekly'])
for year in df['weekly'].dt.year.unique():
    top_countries = df.iloc[:, 1:].sum().nlargest(6).index.tolist()
    agg = df[top_countries].groupby([df['weekly'].dt.year.rename('year'),df['weekly'].dt.week.rename('week')]).sum()

    agg[agg.index.get_level_values(0) == year].droplevel(level=0).plot.bar(stacked = True, figsize = (10,5), title = year)

你可以嘗試這樣的事情:

url = 'https://gist.githubusercontent.com/adamFlyn/a6048e547b5a963c7af356c964d15af6/raw/c57c7915cf14f81edc9d5eadaf14efbd43d3e58a/trade_df.csv'
df_ = pd.read_csv(url, parse_dates=['weekly'])
df_['weekly'] = pd.to_datetime(df_['weekly'])
df_.set_index('weekly', inplace=True)

for g, n in df_.groupby(df_.index.year):
    ng = n.loc[:, n.sum().rank(ascending=False, method='min')<5]
    ng.div(ng.sum(axis=1), axis=0).plot.area(title=f'{g}')

Output:

在此處輸入圖像描述

在此處輸入圖像描述

在此處輸入圖像描述

條形圖:

將 matplotlib.ticker 導入為 mticker

url = 'https://gist.githubusercontent.com/adamFlyn/a6048e547b5a963c7af356c964d15af6/raw/c57c7915cf14f81edc9d5eadaf14efbd43d3e58a/trade_df.csv'
df_ = pd.read_csv(url, parse_dates=['weekly'])
df_['weekly'] = pd.to_datetime(df_['weekly'])
df_.set_index('weekly', inplace=True)

for g, n in df_.groupby(df_.index.year):
    ng = n.loc[:, n.sum().rank(ascending=False, method='min')<5]
    ng.index = ng.index.strftime('%m/%d/%Y')
    ax = ng.plot.bar(stacked=True, figsize=(10,8))

Output:

在此處輸入圖像描述

在此處輸入圖像描述

在此處輸入圖像描述

質押 100% 條形圖:

#(previous code)
ax = ng.div(ng.sum(axis=1), axis=0).plot.bar(stacked=True, figsize=(10,8))

Output: 在此處輸入圖像描述

在此處輸入圖像描述

在此處輸入圖像描述

你可以試試這個

import pandas as pd

# load the data
url = 'https://gist.githubusercontent.com/adamFlyn/a6048e547b5a963c7af356c964d15af6/raw/c57c7915cf14f81edc9d5eadaf14efbd43d3e58a/trade_df.csv'
df = pd.read_csv(url, parse_dates=['weekly'])
df['weekly'] = pd.to_datetime(df['weekly'])
df['year'] = df['weekly'].dt.year
df['week'] = df['weekly'].dt.strftime('%W').astype('int')
df.set_index(['year', 'week'], inplace=True)
df.drop('weekly', axis=1, inplace=True)

df_year_sums = df.groupby(level='year').sum().T

for year in df_year_sums.columns:
    largest = list(df_year_sums[year].nlargest(6).index)  
    df_plot = df.xs(year, level='year')[largest]
    df_plot.plot.bar(stacked=True, title=f'{year} Year', figsize=(8,5))
df=pd.read_csv('trade_df.csv',parse_dates=['weekly'])
 df['weekly']=pd.to_datetime(df['weekly'])
 df['Total']=0
 df.reset_index()
 for key,row in df.iterrows():
     sum=0.0
     for row_value in row:
        if type(row_value)==float:
            sum+=row_value
     df.loc[key,'Total']=sum

 results=df.sort_values(by="Total",ascending=False)

 print(results.head(5))   


 #grouped=df.groupby('year').sum().T.plot.bar(stacked=True)
 #plt.show() 

 filter=df['year'].isin([2018])
 results_2018=df[filter].sort_values(by=['total'],ascending=False).head(5)

 filter=df['year'].isin([2019])
 results_2019=df[filter].sort_values(by=['total'],ascending=False).head(5)

 filter=df['year'].isin([2020])
 results_2020=df[filter].sort_values(by=['total'],ascending=False).head(5)

 grouped=df.groupby('year').sum().T.plot.bar(stacked=True)
 plt.show()

 fp=results_2018.pivot_table(index=['week'],aggfunc='sum').fillna(0)
 fp = fp[(fp.T != 0).any()]

 fp2=results_2019.pivot_table(index=['week'],aggfunc='sum').fillna(0)
 fp2 = fp2[(fp2.T != 0).any()]

 fp3=results_2020.pivot_table(index=['week'],aggfunc='sum').fillna(0)
 fp3 = fp3[(fp3.T != 0).any()]

 #print(fp)
 fig,ax=plt.subplots(3,1,figsize=(16,16))
 fp.plot.bar(stacked=True,ax=ax[0])
 fp2.plot.bar(stacked=True,ax=ax[1])
 fp3.plot.bar(stacked=True,ax=ax[2])
 plt.show()
df = pd.DataFrame(np.random.randint(1,100,(100)),columns=["column1"])
results=np.array(df.sort_values(by="column1",ascending=False)).flatten()
print(results[:5])

暫無
暫無

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

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