Skip to main content
 首页 » 编程设计

python之当第二列包含 NaN/空字符串时,连接 pandas 数据框中的两列而不在末尾添加额外的空格

2025年05月04日34Terrylee

我有以下 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'])