有更快的吗将int列组合成不带TypeE的点分隔str列的方法

2024-09-22 20:34:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想合并两个int列来创建一个新的以点分隔的str列。我有一个办法,但如果有一个更快的办法,它会有所帮助。我还尝试了在另一个答案中找到的一个建议,因此产生了一个错误。你知道吗

这样做有效:

df3 = pd.DataFrame({'job_number': [3913291, 3887250, 3913041],
                   'task_number': [38544, 0, 1]})
df3['filename'] = df3['job_number'].astype(str) + '.' + df3['task_number'].astype(str)

0    3913291.38544
1    3887250.0    
2    3913041.1

This answer对于一个类似的问题,我建议使用.values.astype(str)的“numpy”方式,但我还没有让它起作用。在这里,我运行它时不包括点分隔符:

df3['job_number'].values.astype(int).astype(str) + df3['task_number'].astype(int).astype(str)

0    391329138544
1    38872500    
2    39130411 

但是当我包含点分隔符时,我得到一个错误:

df3['job_number'].values.astype(int).astype(str) + '.' + df3['task_number'].astype(int).astype(str)

TypeError: ufunc 'add' did not contain a loop with signature matching types dtype('<U11') dtype('<U11') dtype('<U11')

我想要的结果是:

0    3913291.38544
1    3887250.0    
2    3913041.1

Tags: 答案numbertask错误job建议intvalues
3条回答

%%timeit结果排序的方法

我对所有建议的方法进行了计时,并在两个数据帧上对更多的方法进行了计时。以下是建议方法的计时结果(谢谢@meW和@jezrael)。如果我错过了任何一个或你有另一个,让我知道,我会添加它。你知道吗

每个方法显示两个计时:首先处理示例df中的3行,然后处理另一个df中的57K行。其他系统的计时可能不同。在连接字符串中包含TEST['dot']的解决方案需要在df中使用此列:用TEST['dot'] = '.'添加它。你知道吗

原始方法(仍然是最快的):

.astype(str),+,'..'.

%%timeit
TEST['filename'] = TEST['job_number'].astype(str) + '.' + TEST['task_number'].astype(str)
# 553 µs ± 6.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 69.6 ms ± 876 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) on 57K rows

建议的方法和一些排列:

.astype(int).astype(str),+,'..'.

%%timeit
TEST['filename'] = TEST['job_number'].astype(int).astype(str) + '.' + TEST['task_number'].astype(int).astype(str)
# 553 µs ± 6.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 70.2 ms ± 739 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) on 57K rows

。值.astype(int).astype(str),+,TEST['dot']

%%timeit
TEST['filename'] = TEST['job_number'].values.astype(int).astype(str) + TEST['dot'] + TEST['task_number'].values.astype(int).astype(str)
# 221 µs ± 5.93 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 82.3 ms ± 743 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) on 57K rows

。值.astype(str),+,测试['dot']

%%timeit
TEST["filename"] = TEST['job_number'].values.astype(str) + TEST['dot'] + TEST['task_number'].values.astype(str)
# 221 µs ± 5.93 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 92.8 ms ± 1.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) on 57K rows

'.'.join(),列表理解。值.astype(str)

%%timeit
TEST["filename"] = ['.'.join(i) for i in TEST[["job_number",'task_number']].values.astype(str)]
# 743 µs ± 19.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 147 ms ± 532 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) on 57K rows

f-string,列表理解。值.astype(str)

%%timeit
TEST["filename2"] = [f'{i}.{j}' for i,j in TEST[["job_number",'task_number']].values.astype(str)]
# 642 µs ± 27.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 167 ms ± 3.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) on 57K rows

.join(),zip,列表理解,.map(str)

%%timeit
TEST["filename"] = ['.'.join(i) for i in 
                          zip(TEST["job_number"].map(str), TEST["task_number"].map(str))]
# 512 µs ± 5.74 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 181 ms ± 4.17 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) on 57K rows

应用(lambda,str(x[2]),+,'.')

%%timeit
TEST['filename'] = TEST.T.apply(lambda x: str(x[2]) + '.' + str(x[10]))
# 735 µs ± 13.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) on 3 rows
# 2.69 s ± 18.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) on 57K rows

如果你发现了一个改进的方法,请告诉我,我会添加到列表中!你知道吗

您可以使用列表理解:

df3["filename"] = ['.'.join(i) for i in 
                          zip(df3["job_number"].map(str),df3["task_number"].map(str))]

如果使用Python3.6+和f-string的最快解决方案:

df3["filename2"] = [f'{i}.{j}' for i,j in zip(df3["job_number"],df3["task_number"])]

30000行的性能:

df3 = pd.DataFrame({'job_number': [3913291, 3887250, 3913041],
                   'task_number': [38544, 0, 1]})
df3 = pd.concat([df3] * 10000, ignore_index=True)


In [64]: %%timeit
    ...: df3["filename2"] = [f'{i}.{j}' for i,j in zip(df3["job_number"],df3["task_number"])]
    ...: 
20.5 ms ± 226 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [65]: %%timeit
    ...: df3["filename3"] = ['.'.join(i) for i in zip(df3["job_number"].map(str),df3["task_number"].map(str))]
    ...: 
30.9 ms ± 189 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [66]: %%timeit
    ...: df3["filename4"] = df3.T.apply(lambda x: str(x[0]) + '.' + str(x[1]))
    ...: 
1.7 s ± 31.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [67]: %%timeit
    ...: df3['dummy'] ='.'
    ...: res = df3['job_number'].values.astype(str) + df3['dummy'] + df3['task_number'].values.astype(str)
    ...: df3.drop(columns=['dummy'], inplace=True)
    ...: 
73.6 ms ± 1.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

但最快的解决方案是:

In [73]: %%timeit
    ...: df3['filename'] = df3['job_number'].astype(str) + '.' + df3['task_number'].astype(str)
48.3 ms ± 872 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

稍加修改-使用map代替astype

In [76]: %%timeit
    ...: df3['filename'] = df3['job_number'].map(str) + '.' + df3['task_number'].map(str)
    ...: 
26 ms ± 676 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

有关给定方法与其他可用方法的比较,请参阅@Jezrael answer。你知道吗

方法1

要添加包含.的伪列,请在处理中使用它,然后删除它:

%%timeit
df3['dummy'] ='.'
res = df3['job_number'].values.astype(str) + df3['dummy'] + df3['task_number'].values.astype(str)
df3.drop(columns=['dummy'], inplace=True)

1.31 ms ± 41.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

对于方法1的扩展,如果排除创建伪列的处理时间并将其删除,则得到的最佳结果是-

%%timeit
df3['job_number'].values.astype(str) + df3['dummy'] + df3['task_number'].values.astype(str)

286 µs ± 15.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

方法2

使用apply

%timeit df3.T.apply(lambda x: str(x[0]) + '.' + str(x[1]))

883 µs ± 22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

相关问题 更多 >