在pandas DataFrame中更改每个组的第一个元素

时间:2017-09-15 14:57:30

标签: python pandas dataframe

我想确保与val2对应的vintage的第一个值为NaN。目前有两个已经NaN,但我想确保0.53也更改为NaN

df = pd.DataFrame({
        'vintage': ['2017-01-01', '2017-01-01', '2017-01-01', '2017-02-01', '2017-02-01', '2017-03-01'],
        'date': ['2017-01-01', '2017-02-01', '2017-03-01', '2017-02-01', '2017-03-01', '2017-03-01'],
        'val1': [0.59, 0.68, 0.8, 0.54, 0.61, 0.6],
        'val2': [np.nan, 0.66, 0.81, 0.53, 0.62, np.nan]
    })

这是我到目前为止所尝试的内容:

df.groupby('vintage').first().val2 #This gives the first non-NaN values, as shown below

vintage
2017-01-01    0.66
2017-02-01    0.53
2017-03-01     NaN

df.groupby('vintage').first().val2 = np.nan #This doesn't change anything
df.val2

0     NaN
1    0.66
2    0.81
3    0.53
4    0.62
5     NaN

2 个答案:

答案 0 :(得分:9)

您无法分配汇总结果,NaN也会忽略现有head(1),您可以执行的操作是调用loc,这将返回每个{1}}的第一行group,并将索引传递给In[91] df.loc[df.groupby('vintage')['val2'].head(1).index, 'val2'] = np.NaN df: Out[91]: date val1 val2 vintage 0 2017-01-01 0.59 NaN 2017-01-01 1 2017-02-01 0.68 0.66 2017-01-01 2 2017-03-01 0.80 0.81 2017-01-01 3 2017-02-01 0.54 NaN 2017-02-01 4 2017-03-01 0.61 0.62 2017-02-01 5 2017-03-01 0.60 NaN 2017-03-01 以掩盖orig df以覆盖这些列值:

head(1)

在这里,您可以看到In[94]: df.groupby('vintage')['val2'].head(1) Out[94]: 0 NaN 3 0.53 5 NaN Name: val2, dtype: float64 返回每个组的第一行:

first

NaN形成对比,后者将返回第一个非NaN,除非该组只有In[95]: df.groupby('vintage')['val2'].first() Out[95]: vintage 2017-01-01 0.66 2017-02-01 0.53 2017-03-01 NaN Name: val2, dtype: float64 个值:

uvm_config_db#(uvm_bitstream_t)::set 

答案 1 :(得分:1)

或者创建位置,选择第一个,将val2更改为np.nan

df.loc[df.groupby('vintage').vintage.cumcount()==0,'val2']=np.nan
df
Out[154]: 
         date  val1  val2     vintage
0  2017-01-01  0.59   NaN  2017-01-01
1  2017-02-01  0.68  0.66  2017-01-01
2  2017-03-01  0.80  0.81  2017-01-01
3  2017-02-01  0.54   NaN  2017-02-01
4  2017-03-01  0.61  0.62  2017-02-01
5  2017-03-01  0.60   NaN  2017-03-01