从数据框中的数字中提取最高位值数字
Extract the highest place value digit from numbers in a dataframe
我有一个 python 数据框,其中有一列名为错误代码:
df1=pd.DataFrame({'errorcodes1':[6321,235,314,421,5346,514,4,3415,136,216,34,623])
我需要一个输出的函数:[6,2,3,4,5,5,4,3,1,2,3,6]。
我想到了把每个错误码都转成字符串,然后提取元素[0]。但是,这涉及字符串操作,从整数转换为整数,这可能很慢。有没有更快的方法?
我认为字符串操作是最好的,或者你可以尝试按长度划分每个数据单元
如果您被禁止转换为 str
,您可以通过以下方式利用布里格斯对数来完成该任务:
import math
numbers = [6321,235,314,421,5346,514,4,3415,136,216,34,623]
def first_digit(n):
return n//10**int(math.log(n, 10))
for n in numbers:
print(n, first_digit(n), sep='\t')
输出:
6321 6
235 2
314 3
421 4
5346 5
514 5
4 4
3415 3
136 1
216 2
34 3
623 6
说明:首先我使用前面提到的对数检测数字中的位数,然后我使用整数除法 (//
) 检查给定数字中有多少 10**(number_of_digits)
。
我测试了哪种方法更快 - log
或 str
- 两者给出的结果相似但 str
稍快一些。如果您不将 str
转换为 int
那么它会更快。您也可以使用 ord()
而不是 int()
来使其更快。
e1 = time.time()
results = [int(str(n)[0]) for n in numbers]
e2 = time.time()
print('int(str): {:.10f}'.format(e2-e1))
e1 = time.time()
results = [n//10**int(math.log(n, 10)) for n in numbers]
e2 = time.time()
print(' log: {:.10f}'.format(e2-e1))
e1 = time.time()
results = [str(n)[0] for n in numbers]
e2 = time.time()
print(' str: {:.10f}'.format(e2-e1))
e1 = time.time()
results = [ord(str(n)[0])-ord('0') for n in numbers]
e2 = time.time()
print('ord(str): {:.10f}'.format(e2-e1))
结果
int(str): 0.0000424385
log: 0.0000514984
str: 0.0000197887
ord(str): 0.0000286102
为了进行更好的测试,我使用了模块 timeit
,它多次运行代码并计算平均时间。
我还使用 df.apply()
检查代码,将 df
转换为 list
,然后将 list
转换为 df
。所有显示用于获取第一个数字的时间非常小,因此在所有计算中都不重要
import pandas as pd
import math
import time
import timeit
def test1():
results = [int(str(n)[0]) for n in numbers]
def test1b():
results = [ord(str(n)[0]) - ord('0') for n in numbers]
def test1c():
results = [str(n)[0] for n in numbers]
def test2():
results = [n//10**int(math.log(n, 10)) for n in numbers]
def test3():
df['number'] = df['errorcodes1'].apply(lambda n:int(str(n)[0]))
def test3b():
df['number'] = df['errorcodes1'].apply(lambda n:ord(str(n)[0])-ord('0'))
def test3c():
df['number'] = df['errorcodes1'].apply(lambda n:str(n)[0])
def test4():
df['number'] = df['errorcodes1'].apply(lambda n:n//10**int(math.log(n, 10)))
def test5():
numbers = df['errorcodes1'].to_list()
results = [int(str(n)[0]) for n in numbers]
df['number'] = results
def test6():
numbers = df['errorcodes1'].to_list()
results = [n//10**int(math.log(n, 10)) for n in numbers]
df['number'] = results
df = pd.DataFrame({'errorcodes1':[6321,235,314,421,5346,514,4,3415,136,216,34,623]})
numbers = df['errorcodes1'].to_list()
print('list log() : {:.5f}'.format(timeit.timeit(test2, number=1000)))
print('list int(str()) : {:.5f}'.format(timeit.timeit(test1, number=1000)))
print('list ord(str()) : {:.5f}'.format(timeit.timeit(test1b, number=1000)))
print('list str() : {:.5f}'.format(timeit.timeit(test1c, number=1000)))
print('---')
print('df.apply(log()) : {:.5f}'.format(timeit.timeit(test4, number=1000)))
print('df.apply(int(str())) : {:.5f}'.format(timeit.timeit(test3, number=1000)))
print('df.apply(ord(str())) : {:.5f}'.format(timeit.timeit(test3b, number=1000)))
print('df.apply(str()) : {:.5f}'.format(timeit.timeit(test3c, number=1000)))
print('---')
print('df -> list int(str()) -> df : {:.5f}'.format(timeit.timeit(test5, number=1000)))
print('df -> list log() -> df : {:.5f}'.format(timeit.timeit(test6, number=1000)))
结果:
list log() : 0.01505
list int(str()) : 0.00917
list ord(str()) : 0.00713
list str() : 0.00463
---
df.apply(log()) : 0.62433
df.apply(int(str())) : 0.61940
df.apply(ord(str())) : 0.60435
df.apply(str()) : 0.64205
---
df -> list int(str()) -> df : 0.27188
df -> list log() -> df : 0.27696
我有一个 python 数据框,其中有一列名为错误代码:
df1=pd.DataFrame({'errorcodes1':[6321,235,314,421,5346,514,4,3415,136,216,34,623])
我需要一个输出的函数:[6,2,3,4,5,5,4,3,1,2,3,6]。
我想到了把每个错误码都转成字符串,然后提取元素[0]。但是,这涉及字符串操作,从整数转换为整数,这可能很慢。有没有更快的方法?
我认为字符串操作是最好的,或者你可以尝试按长度划分每个数据单元
如果您被禁止转换为 str
,您可以通过以下方式利用布里格斯对数来完成该任务:
import math
numbers = [6321,235,314,421,5346,514,4,3415,136,216,34,623]
def first_digit(n):
return n//10**int(math.log(n, 10))
for n in numbers:
print(n, first_digit(n), sep='\t')
输出:
6321 6
235 2
314 3
421 4
5346 5
514 5
4 4
3415 3
136 1
216 2
34 3
623 6
说明:首先我使用前面提到的对数检测数字中的位数,然后我使用整数除法 (//
) 检查给定数字中有多少 10**(number_of_digits)
。
我测试了哪种方法更快 - log
或 str
- 两者给出的结果相似但 str
稍快一些。如果您不将 str
转换为 int
那么它会更快。您也可以使用 ord()
而不是 int()
来使其更快。
e1 = time.time()
results = [int(str(n)[0]) for n in numbers]
e2 = time.time()
print('int(str): {:.10f}'.format(e2-e1))
e1 = time.time()
results = [n//10**int(math.log(n, 10)) for n in numbers]
e2 = time.time()
print(' log: {:.10f}'.format(e2-e1))
e1 = time.time()
results = [str(n)[0] for n in numbers]
e2 = time.time()
print(' str: {:.10f}'.format(e2-e1))
e1 = time.time()
results = [ord(str(n)[0])-ord('0') for n in numbers]
e2 = time.time()
print('ord(str): {:.10f}'.format(e2-e1))
结果
int(str): 0.0000424385
log: 0.0000514984
str: 0.0000197887
ord(str): 0.0000286102
为了进行更好的测试,我使用了模块 timeit
,它多次运行代码并计算平均时间。
我还使用 df.apply()
检查代码,将 df
转换为 list
,然后将 list
转换为 df
。所有显示用于获取第一个数字的时间非常小,因此在所有计算中都不重要
import pandas as pd
import math
import time
import timeit
def test1():
results = [int(str(n)[0]) for n in numbers]
def test1b():
results = [ord(str(n)[0]) - ord('0') for n in numbers]
def test1c():
results = [str(n)[0] for n in numbers]
def test2():
results = [n//10**int(math.log(n, 10)) for n in numbers]
def test3():
df['number'] = df['errorcodes1'].apply(lambda n:int(str(n)[0]))
def test3b():
df['number'] = df['errorcodes1'].apply(lambda n:ord(str(n)[0])-ord('0'))
def test3c():
df['number'] = df['errorcodes1'].apply(lambda n:str(n)[0])
def test4():
df['number'] = df['errorcodes1'].apply(lambda n:n//10**int(math.log(n, 10)))
def test5():
numbers = df['errorcodes1'].to_list()
results = [int(str(n)[0]) for n in numbers]
df['number'] = results
def test6():
numbers = df['errorcodes1'].to_list()
results = [n//10**int(math.log(n, 10)) for n in numbers]
df['number'] = results
df = pd.DataFrame({'errorcodes1':[6321,235,314,421,5346,514,4,3415,136,216,34,623]})
numbers = df['errorcodes1'].to_list()
print('list log() : {:.5f}'.format(timeit.timeit(test2, number=1000)))
print('list int(str()) : {:.5f}'.format(timeit.timeit(test1, number=1000)))
print('list ord(str()) : {:.5f}'.format(timeit.timeit(test1b, number=1000)))
print('list str() : {:.5f}'.format(timeit.timeit(test1c, number=1000)))
print('---')
print('df.apply(log()) : {:.5f}'.format(timeit.timeit(test4, number=1000)))
print('df.apply(int(str())) : {:.5f}'.format(timeit.timeit(test3, number=1000)))
print('df.apply(ord(str())) : {:.5f}'.format(timeit.timeit(test3b, number=1000)))
print('df.apply(str()) : {:.5f}'.format(timeit.timeit(test3c, number=1000)))
print('---')
print('df -> list int(str()) -> df : {:.5f}'.format(timeit.timeit(test5, number=1000)))
print('df -> list log() -> df : {:.5f}'.format(timeit.timeit(test6, number=1000)))
结果:
list log() : 0.01505
list int(str()) : 0.00917
list ord(str()) : 0.00713
list str() : 0.00463
---
df.apply(log()) : 0.62433
df.apply(int(str())) : 0.61940
df.apply(ord(str())) : 0.60435
df.apply(str()) : 0.64205
---
df -> list int(str()) -> df : 0.27188
df -> list log() -> df : 0.27696