【问题标题】:Pandas: convert first value in group to np.nanPandas:将组中的第一个值转换为 np.nan
【发布时间】:2017-07-25 01:21:24
【问题描述】:

我有以下数据框:

df = pd.DataFrame({'series1':['A','A','A','A','B','B','B','C','C','C','C'],
                   'series2':[0,1,10,99,-9,9,0,10,20,10,10]})
   series1  series2
0        A      0.0
1        A      1.0
2        A     10.0
3        A     99.0
4        B     -9.0
5        B      9.0
6        B      0.0
7        C     10.0
8        C     20.0
9        C     10.0
10       C     10.0

我想要什么:

df2 = pd.DataFrame({'series1':['A','A','A','A','B','B','B','C','C','C','C'],
                   'series2':[np.nan,1,10,99,np.nan,9,0,np.nan,20,10,10]})
   series1  series2
0        A      NaN
1        A      1.0
2        A     10.0
3        A     99.0
4        B      NaN
5        B      9.0
6        B      0.0
7        C      NaN
8        C     20.0
9        C     10.0
10       C     10.0

我感觉这可以通过使用 Pandas .groupby 函数来完成:

df.groupby('series1').first()
         series2
series1         
A              0
B             -9
C             10

这给了我想要转换为 NaN 的观察结果,但我想不出一种方法可以轻松地在原始 DataFrame 中替换它。

这只是一个简单的例子,我工作的实际数据框有 >8,000,000 个观察值。

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    可能有一种更巧妙的方法可以做到这一点,但每个组中的第一个元素是该组中的第 0 个元素,cumcount 为每个组中的元素编号。所以:

    In [19]: df.loc[df.groupby('series1').cumcount() == 0, 'series2'] = np.nan
    
    In [20]: df
    Out[20]: 
       series1  series2
    0        A      NaN
    1        A      1.0
    2        A     10.0
    3        A     99.0
    4        B      NaN
    5        B      9.0
    6        B      0.0
    7        C      NaN
    8        C     20.0
    9        C     10.0
    10       C     10.0
    

    【讨论】:

      【解决方案2】:

      您想通过将series1 向下移动并与自身进行比较来定位不连续点:

      df.loc[df['series1'].shift() != df['series1'], 'series2'] = np.nan
      

      【讨论】:

        【解决方案3】:

        移动列的另一种选择:

        df['series2'] = df.groupby('series1').series2.transform(lambda x: x.shift(-1).shift())
        
        df
        #  series1  series2
        #0       A      NaN
        #1       A      1.0
        #2       A     10.0
        #3       A     99.0
        #4       B      NaN
        #5       B      9.0
        #6       B      0.0
        #7       C      NaN
        #8       C     20.0
        #9       C     10.0
        #10      C     10.0
        

        【讨论】:

        • @Wen 谢谢! ^^
        【解决方案4】:

        或者您可以使用headfirstnth 都通过索引切片返回相同的结果。

            df.loc[df.groupby('series1',as_index=False).head(1).index,'series2'] = np.nan
            #df.loc[df.groupby('series1',as_index=False).first().index,'series2'] = np.nan
            #df.loc[df.groupby('series1',as_index=False).nth(1).index,'series2'] = np.nan
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-12
          • 1970-01-01
          • 2020-08-11
          • 2021-07-22
          • 1970-01-01
          • 2020-04-13
          • 2021-09-28
          • 2021-05-02
          相关资源
          最近更新 更多