簡體   English   中英

Python Pandas:將數據從一個數據幀歸一化到另一個數據幀

[英]Python Pandas: Denormalize data from one data frame into another

我有一個Pandas數據框,您可能會將其描述為“規范化”。 出於顯示目的,我想“去標准化”數據。 也就是說,我想將一些數據分布在多個鍵值上,我希望將它們放在輸出記錄的同一行上。 有些記錄在組合時需要求和。 (旁白:如果有人比“非規范化”有更好的術語,請對這個問題進行編輯,或者在評論中這樣說。)

我正在使用包含許多列的pandas數據框,因此我將在下面向您展示一個簡化版本。

以下代碼設置(幾乎)規范化的源數據幀。 (注意,我正在尋找第二個代碼塊的建議,這個代碼塊只是為了提供一些上下文。)與我的實際數據類似,識別數據中有一些重復,有些數字需要求和:

import pandas as pd

dates = pd.date_range('20170701', periods=21)
datesA1 = pd.date_range('20170701', periods=11)
datesB1 = pd.date_range('20170705', periods=9)
datesA2 = pd.date_range('20170708', periods=10)
datesB2 = pd.date_range('20170710', periods=11)
datesC1 = pd.date_range('20170701', periods=5)
datesC2 = pd.date_range('20170709', periods=9)

cols=['Date','Type','Count']

df_A1 = pd.DataFrame({'Date':datesA1,
                      'Type':'Apples',
                      'Count': np.random.randint(30,size=11)})
df_A2 = pd.DataFrame({'Date':datesA2,
                      'Type':'Apples',
                      'Count': np.random.randint(30,size=10)})
df_B1 = pd.DataFrame({'Date':datesB1,
                      'Type':'Berries',
                      'Count': np.random.randint(30,size=9)})
df_B2 = pd.DataFrame({'Date':datesB2,
                      'Type':'Berries',
                      'Count': np.random.randint(30,size=11)})
df_C1 = pd.DataFrame({'Date':datesC1,
                      'Type':'Canteloupes',
                      'Count': np.random.randint(30,size=5)})
df_C2 = pd.DataFrame({'Date':datesC2,
                      'Type':'Canteloupes',
                      'Count': np.random.randint(30,size=9)})

frames = [df_A1, df_A2, df_B1, df_B2, df_C1, df_C2]

dat_fra_source = pd.concat(frames)

此外,以下代碼實現了我的意圖。 源數據框每個日期和水果類型(A,B和C)有多行。 目標數據每天有一行,總和為A,B和C.

dat_fra_dest = pd.DataFrame(0, index=dates, columns=['Apples','Berries','Canteloupes'])

for index,row in dat_fra_source.iterrows():
    dat_fra_dest.at[row['Date'],row['Type']]+=row['Count']

我的問題是,是否有更簡潔的方法:不需要零初始化和/或對整個數據幀而不是逐行操作的方式。 我也懷疑我有一個有效的實施。 我還要注意,雖然我只是在簡化示例中處理“count”,但我的實際示例中還有其他列。 認為對於A,B和C,不僅有計數,還有重量和體積。

選項1

dat_fra_source.groupby(['Date','Type']).sum().unstack().fillna(0)

Out[63]: 
            Count                    
Type       Apples Berries Canteloupes
Date                                 
2017-07-01   13.0     0.0        24.0
2017-07-02   18.0     0.0        16.0
2017-07-03   11.0     0.0        29.0
2017-07-04   13.0     0.0         7.0
2017-07-05   24.0    11.0        23.0
2017-07-06    6.0     4.0         0.0
2017-07-07   29.0    26.0         0.0
2017-07-08   31.0    19.0         0.0
2017-07-09   38.0    17.0        26.0
2017-07-10   57.0    54.0         1.0
2017-07-11    4.0    41.0        10.0
2017-07-12   16.0    28.0        23.0
2017-07-13   25.0    20.0        20.0
2017-07-14   19.0     6.0        15.0
2017-07-15    6.0    22.0         7.0
2017-07-16   16.0     0.0         5.0
2017-07-17   29.0     7.0         4.0
2017-07-18    0.0    21.0         0.0
2017-07-19    0.0    19.0         0.0
2017-07-20    0.0     8.0         0.0

選項2

pd.pivot_table(dat_fra_source,index=['Date'],columns=['Type'],values='Count',aggfunc=sum).fillna(0)
Out[75]: 
Type        Apples  Berries  Canteloupes
Date                                    
2017-07-01    13.0      0.0         24.0
2017-07-02    18.0      0.0         16.0
2017-07-03    11.0      0.0         29.0
2017-07-04    13.0      0.0          7.0
2017-07-05    24.0     11.0         23.0
2017-07-06     6.0      4.0          0.0
2017-07-07    29.0     26.0          0.0
2017-07-08    31.0     19.0          0.0
2017-07-09    38.0     17.0         26.0
2017-07-10    57.0     54.0          1.0
2017-07-11     4.0     41.0         10.0
2017-07-12    16.0     28.0         23.0
2017-07-13    25.0     20.0         20.0
2017-07-14    19.0      6.0         15.0
2017-07-15     6.0     22.0          7.0
2017-07-16    16.0      0.0          5.0
2017-07-17    29.0      7.0          4.0
2017-07-18     0.0     21.0          0.0
2017-07-19     0.0     19.0          0.0
2017-07-20     0.0      8.0          0.0

假設你有列vol和重量

dat_fra_source['vol']=2
dat_fra_source['weight']=2
dat_fra_source.groupby(['Date','Type']).apply(lambda x: sum(x['vol']*x['weight']*x['Count'])).unstack().fillna(0)
Out[88]: 
Type        Apples  Berries  Canteloupes
Date                                    
2017-07-01    52.0      0.0         96.0
2017-07-02    72.0      0.0         64.0
2017-07-03    44.0      0.0        116.0
2017-07-04    52.0      0.0         28.0
2017-07-05    96.0     44.0         92.0
2017-07-06    24.0     16.0          0.0
2017-07-07   116.0    104.0          0.0
2017-07-08   124.0     76.0          0.0
2017-07-09   152.0     68.0        104.0
2017-07-10   228.0    216.0          4.0
2017-07-11    16.0    164.0         40.0
2017-07-12    64.0    112.0         92.0
2017-07-13   100.0     80.0         80.0
2017-07-14    76.0     24.0         60.0
2017-07-15    24.0     88.0         28.0
2017-07-16    64.0      0.0         20.0
2017-07-17   116.0     28.0         16.0
2017-07-18     0.0     84.0          0.0
2017-07-19     0.0     76.0          0.0
2017-07-20     0.0     32.0          0.0

使用pd.crosstab

pd.crosstab(dat_fra_source['Date'],
            dat_fra_source['Type'],
            dat_fra_source['Count'],
            aggfunc='sum',
            dropna=False).fillna(0)

輸出:

Type        Apples  Berries  Canteloupes
Date                                    
2017-07-01    19.0      0.0          4.0
2017-07-02    25.0      0.0          4.0
2017-07-03    11.0      0.0         26.0
2017-07-04    27.0      0.0          8.0
2017-07-05     8.0     18.0         12.0
2017-07-06    10.0     11.0          0.0
2017-07-07     6.0     17.0          0.0
2017-07-08    10.0      5.0          0.0
2017-07-09    51.0     25.0         16.0
2017-07-10    31.0     23.0         21.0
2017-07-11    35.0     40.0         10.0
2017-07-12    16.0     30.0          9.0
2017-07-13    13.0     23.0         20.0
2017-07-14    21.0     26.0         27.0
2017-07-15    20.0     17.0         19.0
2017-07-16    12.0      4.0          2.0
2017-07-17    27.0      0.0          5.0
2017-07-18     0.0      5.0          0.0
2017-07-19     0.0     26.0          0.0
2017-07-20     0.0      6.0          0.0

暫無
暫無

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

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