我有以下 Pandas 数据框:
> print(tpl_subset)
>
Fullname Infrasp Authorship
Lilium abchasicum NaN Baker
Lilium affine NaN Schult. & Schult.f.
Lilium akkusianum NaN Gämperle
Lilium albanicum NaN Griseb.
Lilium albanicum subsp. jankae (A.Kern.) Nyman
Lilium albiflorum NaN Hook.
Lilium album NaN Houtt.
Lilium amabile var. flavum Y.N.Lee
Lilium amabile var. immaculatum T.B.Lee
Lilium amabile var. kwangnungensis Y.S.Kim & W.B.Lee
... ... ...
仅当第二列的值不是 NaN 时,我才尝试将前两列连接成一个新列。
到目前为止,我所做的只是连接两列,同时将 NaN 替换为空字符串。
tpl_subset['Tmp'] = tpl_subset['Fullname'] + ' ' + tpl_subset['Infrasp'].fillna('')
问题是,当第二列的值为 NaN 时,我最终在字符串末尾出现不需要的空格(例如 'Lilium abchasicum' 变为 'Lilium abchasicum '),这迫使我执行额外的步骤来删除它们。
这些步骤将在每个包含数十万行的数据集上重复数百次,因此我正在寻找在性能方面有效的方法。不能选择使用带有 if else 语句的 for 循环。
问:有没有一种更有效、更直接的方法来做到这一点?
所需的列输出是:
Tmp
Lilium abchasicum
Lilium affine
Lilium akkusianum
Lilium albanicum
Lilium albanicum subsp. jankae
Lilium albiflorum
Lilium album
Lilium amabile var. flavum
Lilium amabile var. immaculatum
Lilium amabile var. kwangnungensis
编辑:
numpy.where() 和 radd(' ').fillna('') 在整个数据集(约 120 万行)上的快速性能比较:
In:
import timeit
s = '''
import pandas
import numpy as np
tpl_data = pandas.read_csv('~/phd/Data/TPL/tpl_all_species.csv', sep = '\t')
tpl_fn = tpl_data['Fullname']
tpl_inf = tpl_data['Infrasp']
tpl_concat = tpl_fn + ' ' + tpl_inf
'''
tmp1 = "tpl_data['tmp1'] = np.where(tpl_inf.isnull(), tpl_fn, tpl_concat)"
tmp2 = "tpl_data['tmp2'] = (tpl_fn + tpl_inf.radd(' ').fillna(''))"
print('np.where():', timeit.Timer(tmp1, setup = s).repeat(repeat = 3, number = 10))
print('radd():', timeit.Timer(tmp2, setup = s).repeat(repeat = 3, number = 10))
Out:
np.where(): [0.7466984760000002, 0.7332379689999993, 0.7483021389999998]
radd(): [2.2832963809999995, 2.320076223000001, 2.299452007000003]
请您参考如下方法:
或者使用np.where:
df['Tmp'] = np.where(df['Infrasp'].isnull(), df['Fullname'], df['Fullname'] + ' ' + df['Infrasp'])
