【问题标题】:Applying conditional to grouped data将条件应用于分组数据
【发布时间】:2019-12-23 02:46:38
【问题描述】:

我之前曾针对 R 提出过类似的问题,但我现在正尝试在 python 中复制相同的任务。我在这篇文章中得到的解决方案与我正在寻找的解决方案相似。

Using sapply on column with missing values

基本上我需要根据分组数据有条件地创建一个新列。

以下是一些示例数据:

import pandas as pd

test = pd.DataFrame(data={"Group":[1,1,1,1,1,1,2,2,2,2,2,2],"time": 
[0,1,2,3,4,5,0,1,2,3,4,5],"index": 
[1,1.1,1.4,1.5,1.6,1.67,1,1.4,1.5,1.6,1.93,1.95]})

我现在想创建一个新列“new_index”,它将等于时间 3 之前的索引,但从时间 3 开始以不同的速度增长,比如 10%。所以现在数据看起来像

test2 = pd.DataFrame(data={"Group":[1,1,1,1,1,1,2,2,2,2,2,2],"time": 
[0,1,2,3,4,5,0,1,2,3,4,5],"index": 
[1,1.1,1.4,1.5,1.6,1.67,1,1.4,1.5,1.6,1.93,1.95],"new_index": 
[1,1.1,1.4,1.54,1.694,1.8634,1,1.4,1.5,1.65,1.815,1.9965]})

我尝试了一些这样的代码,但它不起作用

def gr_adj(df):
    if df["time"] <= 2:
        return df["index"]
    else:
        return np.cumprod(df["new_index"])

test["new_index] = test.groupby("Group",group_keys=False).apply(gr_adj)

非常感谢任何帮助,谢谢!

【问题讨论】:

  • 时间列中的值是否循环且始终有序?
  • @SMir 是的,每个组的时间行数相同,并且它们是有序的

标签: python pandas dataframe conditional-statements pandas-groupby


【解决方案1】:

这是使用 cumprod 的一种方法,第一个掩码所有时间超过 3 的索引为 1.1 ,然后我们将输出切片,不包括我们不需要更新的那个,然后我们 groupby 得到 cumprod ,然后将其分配回去

s=test['index'].where(test['time']<3,1.1).loc[test['time']>=2].groupby(test['Group']).cumprod()
test.loc[test['time']>=2,'index']=s
test
Out[290]: 
    Group  time   index
0       1     0  1.0000
1       1     1  1.1000
2       1     2  1.4000
3       1     3  1.5400
4       1     4  1.6940
5       1     5  1.8634
6       2     0  1.0000
7       2     1  1.4000
8       2     2  1.5000
9       2     3  1.6500
10      2     4  1.8150
11      2     5  1.9965

【讨论】:

  • 我最近不得不再次使用这个sn-p的代码,所以非常感谢!我有一个更一般的知识问题是,您如何使用其他系列来获取系列并对其进行过滤/分组? Series 是否将其他 Series 的信息存储在同一个 DataFrame 中?
  • @Elision 因为索引会在 groupby 之前先匹配~
【解决方案2】:

如果时间> 3,这是另一个实际上将您的索引增加 10% 的答案:

import pandas as pd

test = pd.DataFrame(data={"Group":[1,1,1,1,1,1,2,2,2,2,2,2],"time": [0,1,2,3,4,5,0,1,2,3,4,5],"index": [1,1.1,1.4,1.5,1.6,1.67,1,1.4,1.5,1.6,1.93,1.95]})

def gr_adj(row):
    if row["time"] <= 2:
        return row["index"]
    else:
        return row["index"] + (row["index"] * 0.1)

test["new_index"] = test.apply(gr_adj, axis=1)

输出:

    Group  time  index  new_index
0       1     0   1.00      1.000
1       1     1   1.10      1.100
2       1     2   1.40      1.400
3       1     3   1.50      1.650
4       1     4   1.60      1.760
5       1     5   1.67      1.837
6       2     0   1.00      1.000
7       2     1   1.40      1.400
8       2     2   1.50      1.500
9       2     3   1.60      1.760
10      2     4   1.93      2.123
11      2     5   1.95      2.145

这会将您的行的值用作函数的输入并将其应用于每一行。如果time &gt;= 2,它将以index + 10% 的速度增长新索引。

【讨论】:

  • 我认为您的 new_index 列与 OP 想要的不符。
  • @d_kennetz 是的,我希望 new_index 根据之前对自身的观察而增加,因此它在时间 3 后独立于“索引”而增长
猜你喜欢
  • 1970-01-01
  • 2019-12-07
  • 2023-04-07
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多