基于列值对数据帧值进行二值化

时间:2015-02-25 07:16:59

标签: python pandas

我有一个看起来像这样的数据框

+---------+-------------+------------+------------+
| hello   | val1        | val2       | val3       |
+---------+-------------+------------+------------+
| 1.024   | -10.764779  | -8.230176  | -5.689302  |
| 16      | -15.772744  | -10.794013 | -5.79148   |
| 1.024   | -18.4738    | -13.935423 | -9.392713  |
| 0.064   | -11.642506  | -9.711523  | -7.772969  |
| 1.024   | -4.185368   | -2.094441  | 0.048861   |
+---------+-------------+------------+------------+

让此数据框为df。这是我基本上想做的操作

values = ["val1", "val2", "val3"]
for ind in df.index:
    hello = df.loc[ind, "hello"]
    for name in values:
        df.loc[ind, name] = (df.loc[ind, name] >= hello)

基本上对于每一行i和列j,如果val_j小于hello_i,则val_j = False,否则为val_j = True

这显然没有矢量化,而且我的计算机上有这个表的巨型版本,我的电脑在执行这些改动时遇到了麻烦。

上面的操作的矢量化版本是什么?

2 个答案:

答案 0 :(得分:1)

根据hello系列测试整个系列会更快:

In [268]:

val_cols = [col for col in df if 'val' in col]
for col in val_cols:
    df[col] = df[col] >= df['hello']
df    
Out[268]:
    hello   val1   val2   val3
0   1.024  False  False  False
1  16.000  False  False  False
2   1.024  False  False  False
3   0.064  False  False  False
4   1.024  False  False  False

如果我们比较性能:

In [273]:

%%timeit
val_cols = [col for col in df if 'val' in col]
for col in val_cols:
    df[col] = df[col] >= df['hello']
df    
1000 loops, best of 3: 630 µs per loop
In [275]:

%%timeit
column_names = [name for name in df.columns if "val" in name]
binarized = df.apply(lambda row : row[column_names] >= row["hello"], axis=1)
df[binarized.columns] = binarized
df
100 loops, best of 3: 6.17 ms per loop

我们看到我的方法速度提高了10倍,因为它是矢量化的,你的方法基本上是在每一行上循环

答案 1 :(得分:0)

一些实验让我想到了这个

column_names = [name for name in df.columns if "val" in name]
binarized = df.apply(lambda row : row[column_names] >= row["hello"], axis=1)
df[binarized.columns] = binarized

这很有效。