簡體   English   中英

使用包含兩列的groupby的第一行構建新列 - Pandas

[英]Construct new column with first row of a groupby with two columns - Pandas

我試圖構造一個新的列,如果它是第一次“type”列的元素具有列“xx”的特定值,並且在任何其他情況下給出值0,則賦值為1 。

  • 我正在使用的原始數據幀(df)是:

     idx = [np.array(['Jan-18', 'Jan-18', 'Feb-18', 'Mar-18', 'Mar-18', 'Mar-18','Apr-18', 'Apr-18', 'May-18', 'Jun-18', 'Jun-18', 'Jun-18','Jul-18', 'Aug-18', 'Aug-18', 'Sep-18', 'Sep-18', 'Oct-18','Oct-18', 'Oct-18', 'Nov-18', 'Dec-18', 'Dec-18',]),np.array(['A', 'B', 'B', 'A', 'B', 'C', 'A', 'B', 'B', 'A', 'B', 'C','A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'A', 'B', 'C'])] data = [{'xx': 1000}, {'xx': 1000}, {'xx': 1200}, {'xx': 800}, {'xx': 800}, {'xx': 800},{'xx': 1000}, {'xx': 1000}, {'xx': 800}, {'xx': 1200}, {'xx': 1200}, {'xx': 1200},{'xx': 1000}, {'xx': 1000}, {'xx': 1000}, {'xx': 1600}, {'xx': 1600}, {'xx': 1000}, {'xx': 800}, {'xx': 800}, {'xx': 1000}, {'xx': 1600}, {'xx': 1600}] df = pd.DataFrame(data, index=idx, columns=['xx']) df.index.names=['date','type'] df=df.reset_index() df['date'] = pd.to_datetime(df['date'],format = '%b-%y') df=df.set_index(['date','type']) df['xx'] = df.xx.astype('float') 
  • 我要找的結果是:

      xx yy date type 2018-01-01 A 1000.0 1.0 B 1000.0 1.0 2018-02-01 B 1200.0 1.0 2018-03-01 A 800.0 1.0 B 800.0 1.0 C 800.0 1.0 2018-04-01 A 1000.0 0.0 B 1000.0 0.0 2018-05-01 B 800.0 0.0 2018-06-01 A 1200.0 1.0 B 1200.0 0.0 C 1200.0 1.0 2018-07-01 A 1000.0 0.0 2018-08-01 B 1000.0 0.0 C 1000.0 1.0 2018-09-01 A 1600.0 1.0 B 1600.0 1.0 2018-10-01 C 1000.0 0.0 A 800.0 0.0 B 800.0 0.0 2018-11-01 A 1000.0 0.0 2018-12-01 B 1600.0 0.0 C 1600.0 1.0 
  • 我嘗試了以下代碼,但它不起作用(它給出了錯誤消息):

     df['yy'] = df.assign(zz=(df.groupby(['type','xx']).first())).zz.transform(lambda x: 1) 

錯誤消息說

ValueError:傳遞0的項目數錯誤,展示位置意味着1。

我嘗試了其他metodhos,例如nth(0),但它也不起作用。 任何關於如何解決這個問題的建議都是非常受歡迎的。

嘗試:

df['yy'] = (df.groupby(level=1).xx
              .apply(lambda x: (~x.duplicated()).astype(int))
           )

df['yy']

輸出:

date        type
2018-01-01  A       1
            B       1
2018-02-01  B       1
2018-03-01  A       1
            B       1
            C       1
2018-04-01  A       0
            B       0
2018-05-01  B       0
2018-06-01  A       1
            B       0
            C       1
2018-07-01  A       0
2018-08-01  B       0
            C       1
2018-09-01  A       1
            B       1
2018-10-01  C       0
            A       0
            B       0
2018-11-01  A       0
2018-12-01  B       0
            C       1
Name: yy, dtype: int32

使用groupby + cumcount + astype

df['yy'] = df.reset_index().groupby(['type','xx']).cumcount().eq(0).astype(int).values

結果:

                     xx  yy
date       type            
2018-01-01 A     1000.0   1
           B     1000.0   1
2018-02-01 B     1200.0   1
2018-03-01 A      800.0   1
           B      800.0   1
           C      800.0   1
2018-04-01 A     1000.0   0
           B     1000.0   0
2018-05-01 B      800.0   0
2018-06-01 A     1200.0   1
           B     1200.0   0
           C     1200.0   1
2018-07-01 A     1000.0   0
2018-08-01 B     1000.0   0
           C     1000.0   1
2018-09-01 A     1600.0   1
           B     1600.0   1
2018-10-01 C     1000.0   0
           A      800.0   0
           B      800.0   0
2018-11-01 A     1000.0   0
2018-12-01 B     1600.0   0
           C     1600.0   1

duplicated

  • 生成具有typexx的元組列表
  • 將它包裝在pandas.Series因為我想使用pandas.Series.duplicated方法
  • 使用numpy.where01之間進行選擇

注意:這不使用groupby ,因此應該更有效。


s = pd.Series([*zip(df.index.get_level_values('type'), df.xx)])
df.assign(id=np.where(s.duplicated(), 0, 1))

                     xx  id
date       type            
2018-01-01 A     1000.0   1
           B     1000.0   1
2018-02-01 B     1200.0   1
2018-03-01 A      800.0   1
           B      800.0   1
           C      800.0   1
2018-04-01 A     1000.0   0
           B     1000.0   0
2018-05-01 B      800.0   0
2018-06-01 A     1200.0   1
           B     1200.0   0
           C     1200.0   1
2018-07-01 A     1000.0   0
2018-08-01 B     1000.0   0
           C     1000.0   1
2018-09-01 A     1600.0   1
           B     1600.0   1
2018-10-01 C     1000.0   0
           A      800.0   0
           B      800.0   0
2018-11-01 A     1000.0   0
2018-12-01 B     1600.0   0
           C     1600.0   1

IIUC

idx=df.groupby([df.index.get_level_values(1),df.xx]).head(1).index
df.loc[:,'new']=0
df.loc[idx,'new']=1
df
Out[869]: 
                     xx  new
date       type             
2018-01-01 A     1000.0    1
           B     1000.0    1
2018-02-01 B     1200.0    1
2018-03-01 A      800.0    1
           B      800.0    1
           C      800.0    1
2018-04-01 A     1000.0    0
           B     1000.0    0
2018-05-01 B      800.0    0
2018-06-01 A     1200.0    1
           B     1200.0    0
           C     1200.0    1
2018-07-01 A     1000.0    0
2018-08-01 B     1000.0    0
           C     1000.0    1
2018-09-01 A     1600.0    1
           B     1600.0    1
2018-10-01 C     1000.0    0
           A      800.0    0
           B      800.0    0
2018-11-01 A     1000.0    0
2018-12-01 B     1600.0    0
           C     1600.0    1

暫無
暫無

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

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