Pandas DataFrame 转换为二进制

6

给定具有“0.0 < values < 1.0”的pd.DataFrame,我想根据定义的阈值eps = 0.5将其转换为二进制值0/1

      0     1     2
0  0.35  0.20  0.81
1  0.41  0.75  0.59
2  0.62  0.40  0.94
3  0.17  0.51  0.29

目前我只有这个for循环,对于大数据集来说需要很长时间:

import numpy as np
import pandas as pd

data = np.array([[.35, .2, .81],[.41, .75, .59],
                [.62, .4, .94], [.17, .51, .29]])

df = pd.DataFrame(data, index=range(data.shape[0]), columns=range(data.shape[1]))
eps = .5
b = np.zeros((df.shape[0], df.shape[1]))
for i in range(df.shape[0]):
    for j in range(df.shape[1]):
        if df.loc[i,j] < eps:
            b[i,j] = 0
        else:
            b[i,j] = 1
df_bin = pd.DataFrame(b, columns=df.columns, index=df.index)

有人知道更有效的将数值转换为二进制的方法吗?

     0    1    2
0  0.0  0.0  1.0
1  0.0  1.0  1.0
2  1.0  0.0  1.0
3  0.0  1.0  0.0

Thanks,

3个回答

9

df.round

>>> df.round()

np.round

>>> np.round(df)

astype

>>> df.ge(0.5).astype(int)

所有这些都产生

     0    1    2
0  0.0  0.0  1.0
1  0.0  1.0  1.0
2  1.0  0.0  1.0
3  0.0  1.0  0.0

注意:round 能够工作是因为它会自动将介于两个整数间的 .5 设定为阈值。如需使用自定义阈值,请使用第三种解决方案。

8

您也可以使用np.where()函数将值分配给底层数组:

df[:]=np.where(df<0.5,0,1)

   0  1  2
0  0  0  1
1  0  1  1
2  1  0  1
3  0  1  0

4

鉴于我们已经有了一些不同方法的答案,我很好奇它们之间的速度比较。我想分享一下:

# create big test dataframe
dfbig = pd.concat([df]*200000, ignore_index=True)
print(dfbig.shape)

(800000, 3)

# pandas round()
%%timeit 
dfbig.round()

101 ms ± 4.63 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# numpy round()
%%timeit
np.round(dfbig)

104 ms ± 2.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# pandas .ge & .astype
%%timeit
dfbig.ge(0.5).astype(int)

9.32 ms ± 170 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# numpy.where
%%timeit
np.where(dfbig<0.5, 0, 1)

21.5 ms ± 421 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

结论:

  1. pandas中的 geastype
  2. np.where
  3. np.round
  4. pandas中的 round

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接