基于行和列条件设置pandas dataframe值

2024-09-24 06:21:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个相当具体的算法,我想遵循。

基本上我有一个数据框架,如下所示:

        month   taken   score
1       1       2       23
2       1       1       34
3       1       2       12
4       1       2       59
5       2       1       12
6       2       2       23
7       2       1       43
8       2       2       45
9       3       1       43
10      3       2       43
11      4       1       23
12      4       2       94

我想让“分数”列在“得分”栏被更改为100天,在该月底之前,持续地取==2。因此,如果在该月内的任何一天中,所发生的次数==2的分数都设置为100,则为=1。

所以我想要的结果是:

^{pr2}$

我写了这个代码,我觉得应该这样做:

^{pr3}$

但是,尽管没有抛出错误,但这似乎不会改变任何值。。。它也不会给我设置值到复制数据帧的错误。

有人能解释我做错什么了吗?


Tags: 数据代码算法框架错误次数分数taken
2条回答

值没有被更新的原因是对iloc的赋值会更新前面的loc调用返回的copy,因此原始值不会被触及。在


下面是我如何处理这个问题。首先,定义一个函数foo。在

def foo(df):
    for i in reversed(df.index):
        if df.loc[i, 'taken'] != 2:
            break
        df.loc[i, 'score'] = 100
        i -= 1
    return df

现在,groupbymonth并调用foo

^{pr2}$

显然,apply有它的缺点,但是我想不出一种向量化的方法来解决这个问题。在

你能做到的

import numpy as np
def get_value(x):
    s = x['taken']
    # Get a mask of duplicate sequeence and change values using np.where
    mask = s.ne(s.shift()).cumsum().duplicated(keep=False)
    news = np.where(mask,100,x['score'])

    # if last number is 2 then change the news value to 100
    if s[s.idxmax()] == 2: news[-1] = 100 
    return pd.Series(news)

df['score'] = df.groupby('month').apply(get_value).values

输出:

^{pr2}$

几乎相同的速度,但“冷速”是赢家

ndf = pd.concat([df]*10000).reset_index(drop=True)

%%timeit
ndf['score'] = ndf.groupby('month').apply(foo)
10 loops, best of 3: 40.8 ms per loop


%%timeit  
ndf['score'] = ndf.groupby('month').apply(get_value).values
10 loops, best of 3: 42.6 ms per loop

相关问题 更多 >