当前位置: 首页 > 面试题库 >

Python-加快将分类变量转换为其数字索引的速度

鞠征
2023-03-14
问题内容

我需要将Pandas数据框中的一列分类变量转换为与索引相对应的数值,并将其转换为该列中唯一分类变量的数组(长话短说!),这是一个实现以下目的的代码段:

import pandas as pd
import numpy as np

d = {'col': ["baked","beans","baked","baked","beans"]}
df = pd.DataFrame(data=d)
uniq_lab = np.unique(df['col'])

for lab in uniq_lab:
    df['col'].replace(lab,np.where(uniq_lab == lab)[0][0].astype(float),inplace=True)

转换数据帧:

    col
 0  baked
 1  beans
 2  baked
 3  baked
 4  beans

放入数据框:

    col
 0  0.0
 1  1.0
 2  0.0
 3  0.0
 4  1.0

如预期的。但是我的问题是,当我尝试在大数据文件上运行类似代码时,我的傻傻的for循环(我想到的唯一方式)会像糖蜜一样缓慢。我只是想知道是否有人想到是否有任何方法可以更有效地做到这一点。预先感谢您的任何想法。


问题答案:

用途factorize

df['col'] = pd.factorize(df.col)[0]
print (df)
   col
0    0
1    1
2    0
3    0
4    1

文件

编辑:

Jeff评论中所述,那么最好是将column转换为,categorical主要是因为更少的内存使用量:

df['col'] = df['col'].astype("category")

时间

有趣的是,在大dfpandas中,速度更快numpy。我不敢相信。

len(df)=500k

In [29]: %timeit (a(df1))
100 loops, best of 3: 9.27 ms per loop

In [30]: %timeit (a1(df2))
100 loops, best of 3: 9.32 ms per loop

In [31]: %timeit (b(df3))
10 loops, best of 3: 24.6 ms per loop

In [32]: %timeit (b1(df4))
10 loops, best of 3: 24.6 ms per loop

len(df)=5k

In [38]: %timeit (a(df1))
1000 loops, best of 3: 274 µs per loop

In [39]: %timeit (a1(df2))
The slowest run took 6.71 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 273 µs per loop

In [40]: %timeit (b(df3))
The slowest run took 5.15 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 295 µs per loop

In [41]: %timeit (b1(df4))
1000 loops, best of 3: 294 µs per loop

len(df)=5

In [46]: %timeit (a(df1))
1000 loops, best of 3: 206 µs per loop

In [47]: %timeit (a1(df2))
1000 loops, best of 3: 204 µs per loop

In [48]: %timeit (b(df3))
The slowest run took 6.30 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 164 µs per loop

In [49]: %timeit (b1(df4))
The slowest run took 6.44 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 164 µs per loop

测试代码

d = {'col': ["baked","beans","baked","baked","beans"]}
df = pd.DataFrame(data=d)
print (df)
df = pd.concat([df]*100000).reset_index(drop=True)
#test for 5k
#df = pd.concat([df]*1000).reset_index(drop=True)


df1,df2,df3, df4 = df.copy(),df.copy(),df.copy(),df.copy()

def a(df):
    df['col'] = pd.factorize(df.col)[0]
    return df

def a1(df):
    idx,_ = pd.factorize(df.col)
    df['col'] = idx
    return df

def b(df):
    df['col'] = np.unique(df['col'],return_inverse=True)[1]
    return df

def b1(df):
    _,idx = np.unique(df['col'],return_inverse=True)
    df['col'] = idx    
    return df

print (a(df1))    
print (a1(df2))   
print (b(df3))   
print (b1(df4))


 类似资料:
  • 在Objective-C中,我使用了以下内容:

  • 问题内容: 我有任何字符串。像“水牛” 我想将此字符串转换为某些变量名称,例如, 不仅是这个例子,我还想将任何输入字符串转换为某个变量名。我该怎么做(在python中)? 问题答案: 之后,你可以通过以下方式进行检查: 作为输出,你将看到:

  • 问题内容: 为了将字典条目转换为变量,是否存在一种将字典的值分配给其键的pythonic方法?我尝试了这个: 更新:也许我应该更具体一些:实际上,我可以肯定键值对是正确的,因为以前我曾将它们定义为变量。然后,我将这些变量存储在字典中(作为键值对),并希望在其他函数中重用它们。我可以在新函数中重新定义它们,但是由于我的字典可能包含约20个条目,因此我认为可能会有更有效的方法。 问题答案: 这就是我想

  • 问题内容: 如何快速将数组转换为 JSON 字符串?基本上,我有一个文本框,其中嵌入了一个按钮。按下按钮后,文本字段文本将添加到中。此外,我想将此数组转换为 JSON 字符串。 这是我尝试过的: 我也想使用我的方法返回 JSON 字符串。 问题答案: 就目前而言,您正在将其转换为数据,然后尝试将数据转换为JSON形式的对象(失​​败,不是JSON)并将其转换为字符串,基本上,您进行了一堆毫无意义的

  • 问题内容: 我有一个映射到Swift的C函数定义为: 我正在尝试传递函数的路径并尝试过: 但是在path [i]上我得到了错误: ‘下标’不可用:不能下标Int范围的字符串 也不 也不管用 除了无法正常工作外,我认为还必须有一种更好,更轻松的方法来做到这一点。以前使用CString在StackOverflow上的答案似乎不再起作用。有什么建议? 问题答案: 使用CString在StackOverf

  • 问题内容: 我知道如何在Java中执行此操作,但是找不到Java的ByteBuffer的快速等效项,因此也找不到它的.putDouble(double value)方法。 基本上,我正在寻找这样的功能: 问题答案: typealias Byte = UInt8 但是结果与您的期望相反(由于字节顺序): 添加: 对于Xcode8 / Swift3.0: 对于Xcode8.1 / Swift3.0.1