lambda函数用于比较数据框中的两个连续行并创建一个新列

时间:2018-04-01 11:38:21

标签: python pandas

我有一个数据框df['y0', 'size],其中有两列。

y0的浮点值从25.0到800.0
size是一个float数据类型,其值为8到25.

import pandas as pd

data = '''\
y0    Size
25    8  
37    8.7  
68.5  9.3  
93.4  11.4  
110.7  14.6  
145.6  12.1  
180.3  10.9'''

df = pd.read_csv(pd.compat.StringIO(data), sep='\s+')

依旧......

期望的输出
创建一个新列[y0Dash],它具有以下逻辑:

MIN_Y0_DIFF = 0.3

if ((df['y0'] - df[['y0'].shift(-1)]) /
           ((df['Size'] + df[['Size'].shift(-1)]) / 2) < MIN_Y0_DIFF) ):
    df['y0Dash'] = df['y0']
else:
    df['y0Dash'] = df['y0'].shift(-1)

我收到错误,我正在尝试将标量值与系列进行比较,我明白这一点 - 我正在尝试与MIN_Y0_DIFF进行比较。

但是,我没有得到如何在lambda函数中执行此操作。如何比较两个连续的行以获得我想要的结果?

我尝试了什么

def columnCompare():  
    if ((df['y0'] - df[['y0'].shift(-1)]) /
               ((df['Size'] + df[['Size'].shift(-1)]) / 2) < MIN_Y0_DIFF) ):
        df['y0Dash'] = df['y0']
    else:
        df['y0Dash'] = df['y0'].shift(-1)


df = df.apply(lambda x: columnCompare)

1 个答案:

答案 0 :(得分:1)

您不应该使用lambda功能。如果我理解你的逻辑,你可以计算一个布尔掩码,并以矢量化的方式应用你的逻辑。

主要问题似乎是您尝试实施pd.Series.shift的方式:df[['Size'].shift(-1)]不正确,因为list没有shift方法。

MIN_Y0_DIFF = 0.3
mask = (df['y0'] - df['y0'].shift(-1)) / \
       ((df['Size'] + df['Size'].shift(-1)) / 2) < MIN_Y0_DIFF

df.loc[mask, 'y0Dash'] = df['y0']
df.loc[~mask, 'y0Dash'] = df['y0'].shift(-1)

结果:

      y0  Size  y0Dash
0   25.0   8.0    25.0
1   37.0   8.7    37.0
2   68.5   9.3    68.5
3   93.4  11.4    93.4
4  110.7  14.6   110.7
5  145.6  12.1   145.6
6  180.3  10.9     NaN