【问题标题】:Combine arbitrary number of columns into one in pandas在 pandas 中将任意数量的列合并为一列
【发布时间】:2015-09-02 18:17:56
【问题描述】:

这个问题是关于here 的具体案例的一般版本。

我有一个 pandas 数据框,其中的列包含整数。我想将所有这些整数连接成一列中的字符串。

鉴于this answer,对于特定的列,这有效:

(dl['ungrd_dum'].map(str) +
 dl['mba_dum'].map(str) +
 dl['jd_dum'].map(str) +
 dl['ma_phd_dum'].map(str))

但假设我有许多(数百个)这样的列,它们的名称在列表dummies 中。我敢肯定,有一些很酷的 Pythonic 方法可以用一条神奇的线来完成这一切。我已经尝试将mapdummies 一起使用,但还没有弄清楚。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    IIUC 你应该可以做到

    df[dummies].astype(str).apply(lambda x: ''.join(x), axis=1)
    

    例子:

    In [12]:
    
    df = pd.DataFrame({'a':np.random.randint(0,100, 5), 'b':np.arange(5), 'c':np.random.randint(0,10,5)})
    df
    Out[12]:
        a  b  c
    0   5  0  2
    1  46  1  3
    2  86  2  4
    3  85  3  9
    4  60  4  4
    In [15]:
    
    cols=['a','c']
    df[cols].astype(str).apply(''.join, axis=1)
    Out[15]:
    0     52
    1    463
    2    864
    3    859
    4    604
    dtype: object
    

    编辑

    正如@JohnE 所指出的,您可以致电sum,这样会更快:

    df[cols].astype(str).sum(axis=1)
    

    但是,这会将 dtype 隐式转换为 float64,因此您必须再次转换回 str 并在必要时切掉小数点:

    df[cols].astype(str).sum(axis=1).astype(str).str[:-2]
    

    【讨论】:

    • 确实,您完全理解。谢谢。
    • (记住你可以用''.join代替lambda x: ''.join(x)。)
    • @DSM 确实有时我在不需要 lambda 时会忘记
    • 为什么不使用sum,一旦它们是字符串? df.astype(str).sum(axis=1)
    • @JohnE 虽然可行,但 dtype 转换为 float64 OP 想要 str 所以你必须再次将它转换回 str 但对于大型 dfs 可能更快
    【解决方案2】:
    from operator import add
    reduce(add, (df[c].astype(str) for c in cols), "")
    

    例如:

    df = pd.DataFrame({'a':np.random.randint(0,100, 5), 
                       'b':np.arange(5), 
                       'c':np.random.randint(0,10,5)})
    
    cols = ['a', 'c']
    
    
    In [19]: df
    Out[19]: 
        a  b  c
    0   6  0  4
    1  59  1  9
    2  13  2  5
    3  44  3  1
    4  79  4  4
    
    In [20]: reduce(add, (df[c].astype(str) for c in cols), "")
    Out[20]: 
    0     64
    1    599
    2    135
    3    441
    4    794
    dtype: object
    

    【讨论】:

    • 我已经准备好一个漂亮的锡箔盾牌,任何人都准备好在我使用reduce 时扔石头了:)
    【解决方案3】:

    您需要做的第一件事是尽可能高效地将数字数据框转换为字符串数据框:

    dl = dl.astype(str)
    

    那么,您的情况与as this other question 相同,并且可以使用与this answer 中相同的Series.str 访问器技术:

    .str.cat()

    使用str.cat() 你可以这样做:

    dl['result'] = dl[dl.columns[0]].str.cat([dl[c] for c in dl.columns[1:]], sep=' ')

    str.join()

    要使用.str.join(),您需要一系列可迭代对象,比如元组。

    df['result'] = df[df.columns[1:]].apply(tuple, axis=1).str.join(' ')
    

    不要使用list 而不是tuple 尝试上述方法,否则apply() 方法将返回Dataframe,并且数据帧没有.str 访问器,如Series

    【讨论】:

    • Cat 对我来说似乎更快。 Lambda 进行 1 次迭代大约需要 3 秒,但 cat 仅需要 0.08 秒进行相同的迭代。
    猜你喜欢
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2018-11-12
    • 2019-10-19
    • 2016-01-10
    相关资源
    最近更新 更多