通过创建新列来分组熊猫数据框

时间:2021-01-10 00:21:13

标签: pandas pandas-groupby aggregate

我有一个以下格式的数据框:

name         date           
Anne         2018/07/04 
Anne         2018/07/06
Bob          2015/10/01
Bob          2015/10/10
Bob          2015/11/11
Anne         2018/07/05
...          ...

我想添加一列,表示从该人的最短日期开始的相对天数。

对于每一行:

relative_day = (person's date) - (minimum of person's date)

输出为:

name         date           relative_day     
Anne         2018/07/04     0
Anne         2018/07/04     2
Bob          2015/10/01     0
Bob          2015/10/01     9
Bob          2015/11/11     41
Anne         2018/07/05     1

我尝试先按名称分组,然后在每个名称上写一个 for 循环并添加一列,但它给出了错误

<块引用>

试图在 DataFrame 中切片的副本上设置值。

这是我迄今为止尝试过的代码:

df['relative_day'] = None
person_groups = df.groupby('name')
for person_name, person_dates in person_groups:
    person_dates['relative_day'] = person_dates['date'].min()

3 个答案:

答案 0 :(得分:2)

获取名称作为索引,对名称进行分组,然后减去最小值以获得您的相对日期。

result = df.astype({"date": np.datetime64}).set_index("name")
result.assign(relative_day=result['date'] - result.groupby("name")['date'].transform("min"))
         date   relative_day
name        
Anne    2018-07-04  0 days
Anne    2018-07-06  2 days
Bob     2015-10-01  0 days
Bob     2015-10-10  9 days
Bob     2015-11-11  41 days
Anne    2018-07-05  1 days

答案 1 :(得分:1)

@sammywemmy 有一个很好的解决方案。我想展示另一种可能的方式。

import pandas as pd 

# read dataset
df = pd.read_csv('data.csv')

# change column data type
df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d')

# group by name
df_group = df.groupby('name')

# get minimum date value
df_group_min = df_group['date'].min()

# create minimum date column by name
df['min'] = df.apply(lambda r: df_group_min[r['name']], axis=1)

# calculate relative day
df['relative_day'] = (df['date'] - df['min']).dt.days

# remove minimum column
df.drop('min', axis=1, inplace=True)

print(df)

输出

   name       date  relative_day
0  Anne 2018-07-04             0
1  Anne 2018-07-06             2
2   Bob 2015-10-01             0
3   Bob 2015-10-10             9
4   Bob 2015-11-11            41
5  Anne 2018-07-05             1

答案 2 :(得分:1)

让我们试试

df.date=pd.to_datetime(df.date)
df['new'] = (df.date - df.groupby('name').date.transform('min')).dt.days
df
   name       date  new
0  Anne 2018-07-04    0
1  Anne 2018-07-06    2
2   Bob 2015-10-01    0
3   Bob 2015-10-10    9
4   Bob 2015-11-11   41
5  Anne 2018-07-05    1