Python:numpy/pandas根据条件更改值

2024-06-17 10:05:58 发布

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

我想知道是否有一种更快、更“Python式”的方法来完成以下工作,例如使用一些内置的方法。 给定pandas数据帧或numpy浮点数组,如果该值等于或小于0.5,则需要计算倒数并乘以-1,然后用新计算的值替换旧值。 “转换”可能是一个不好的词,请告诉我,如果你有更好/更准确的描述。

谢谢你的帮助和支持!!

数据:

import numpy as np
import pandas as pd
dicti = {"A" : np.arange(0.0, 3, 0.1), 
         "B" : np.arange(0, 30, 1),
         "C" : list("ELVISLIVES")*3}
df = pd.DataFrame(dicti)

我的功能:

def transform_colname(df, colname):
    series = df[colname]    
    newval_list = []
    for val in series:
        if val <= 0.5:
            newval = (1/val)*-1
            newval_list.append(newval)
        else:
            newval_list.append(val)
    df[colname] = newval_list
    return df

函数调用:

transform_colname(df, colname="A")

**-->;我在这里总结结果,因为评论不允许发布代码(或者我不知道如何发布代码)。**

感谢大家快速而精彩的回答!!

将ipython“%timeit”与“real”数据一起使用:

我的功能: 10个回路,最好3个:每个回路24.1 ms

来自jojo:

def transform_colname_v2(df, colname):
    series = df[colname]        
    df[colname] = np.where(series <= 0.5, 1/series*-1, series)
    return df

100个回路,最好3个:每个回路2.76ms

来自FooBar:

def transform_colname_v3(df, colname):
    df.loc[df[colname] <= 0.5, colname]  = - 1 / df[colname][df[colname] <= 0.5]
    return df

100个回路,最好3个:每个回路3.32 ms

来自dmvianna:

def transform_colname_v4(df, colname):
    df[colname] = df[colname].where(df[colname] <= 0.5, (1/df[colname])*-1)
    return df

100个回路,最好3个:每个回路3.7 ms

请告诉/告诉我您是否会以不同的方式实现您的代码!

最后一个问题:(回答) “FooBar”和“dmvianna”的版本如何才能成为“通用的”?我的意思是,我必须将列的名称写入函数中(因为将它用作变量不起作用)。请解释最后一点! -->;谢谢jojo,“.loc”不是正确的方法,但是非常简单的df[colname]就足够了。将上面的函数更改为更“通用”。(也将“>;”更改为“<;=”,并更新计时)

非常感谢!!


Tags: 数据方法代码gtdfreturndefnp
3条回答

正如@jojo的回答,但是使用熊猫:

df.A = df.A.where(df.A > 0.5, (1/df.A)*-1)

或者

df.A.where(df.A > 0.5, (1/df.A)*-1, inplace=True) # this should be faster

。其中docstring:

Definition: df.A.where(self, cond, other=nan, inplace=False, axis=None, level=None, try_cast=False, raise_on_error=True)

Docstring: Return an object of same shape as self and whose corresponding entries are from self where cond is True and otherwise are from other.

典型的技巧是编写一个通用的数学运算来应用于整个列,然后使用指示符来选择实际应用它的行:

df.loc[df.A < 0.5, 'A']  = - 1 / df.A[df.A < 0.5] 

In[13]: df
Out[13]: 
            A   B  C
0        -inf   0  E
1  -10.000000   1  L
2   -5.000000   2  V
3   -3.333333   3  I
4   -2.500000   4  S
5    0.500000   5  L
6    0.600000   6  I
7    0.700000   7  V
8    0.800000   8  E
9    0.900000   9  S
10   1.000000  10  E
11   1.100000  11  L
12   1.200000  12  V
13   1.300000  13  I
14   1.400000  14  S
15   1.500000  15  L
16   1.600000  16  I
17   1.700000  17  V
18   1.800000  18  E
19   1.900000  19  S
20   2.000000  20  E
21   2.100000  21  L
22   2.200000  22  V
23   2.300000  23  I
24   2.400000  24  S
25   2.500000  25  L
26   2.600000  26  I
27   2.700000  27  V
28   2.800000  28  E
29   2.900000  29  S

如果我们说的是数组:

import numpy as np
a = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6], dtype=np.float)
print 1 / a[a <= 0.5] * (-1)

但是,这将只返回小于0.5的值。

或者使用np.where

import numpy as np
a = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6], dtype=np.float)
print np.where(a < 0.5, 1 / a * (-1), a)

谈论pandas数据帧

正如@dmvianna的答案(所以给他点信任;),使其适应pd.DataFrame

df.a = df.a.where(df.a > 0.5, (1 / df.a) * (-1))

相关问题 更多 >