如何在不使用 where 函数的情况下根据 pandas DataFrame 下的其他列有条件地 select 列?

How to conditionally select column based on other columns under pandas DataFrame without using where function?

我在 python 2.5 下工作(由于外部 api,我只能使用该版本)并且希望获得与我在 python 2.7 下编写的代码相同的结果

import pandas as pd
df = pd.DataFrame({"lineId":[1,2,3,4], "idCaseMin": [10, 23, 40, 8], "min": [-110, -205, -80, -150], "idCaseMax": [5, 27, 15, 11], "max": [120, 150, 110, 90]})
df = df.set_index("lineId")

df["idMax"] = df["idCaseMax"].where(df["max"]>abs(df["min"]),df["idCaseMin"])

DataFrame 结果为:

>>> df
        idCaseMax  max  idCaseMin  min  idMax
lineId                                       
1               5   10        120 -110      5
2              27   23        150 -205     23
3              15   40        110  -80     15
4              11    8         90 -150      8

idMax 列是根据获得最大值的 id 定义的,在绝对模块中,在 maxmin 列中。

我无法使用 where 功能,因为它在 pandas 0.9.0(最新版本适用于 python 2.5)和 numpy 1.7.1.

下不可用

那么,在不使用 pandas where 函数的情况下,我必须使用哪些选项才能为 idMax 列获得相同的结果?

我们可以使用下面代码中的apply函数来尝试相同的结果:

df["idMax"] = df.apply(lambda row: row["idCaseMax"] if row["max"]>abs(row["min"]) else row["idCaseMin"], axis = 1)

IIUC 你可以使用 numpy.where():

In [120]: df['idMax'] =  \
              np.where(df["max"]<=abs(df["min"]),
                       df["idCaseMin"],
                       df["idCaseMax"])

In [121]: df
Out[121]:
        idCaseMax  idCaseMin  max  min  idMax
lineId
1               5         10  120 -110      5
2              27         23  150 -205     23
3              15         40  110  -80     15
4              11          8   90 -150      8

我会尝试为 0.9. IIUC ix 提供优化的解决方案应该在这里工作。

m = df["max"] > df["min"].abs()

i = df.ix[m, 'idCaseMax']
j = df.ix[~m, 'idCaseMin']

df['idMax'] = i.append(j)
df

        idCaseMax  idCaseMin  max  min  idMax
lineId
1               5         10  120 -110      5
2              27         23  150 -205     23
3              15         40  110  -80     15
4              11          8   90 -150      8

你的 pandas 应该有这个...

df['idMax']=(df["max"]>abs(df["min"]))* df["idCaseMax"]+(df["max"]<=abs(df["min"]))* df["idCaseMin"]
df
Out[1388]: 
        idCaseMax  idCaseMin  max  min  idMax
lineId                                       
1               5         10  120 -110      5
2              27         23  150 -205     23
3              15         40  110  -80     15
4              11          8   90 -150      8