将 pandas 列转换为连接字符串

Convert pandas columns to concatenated strings

假设我有以下 DataFrame:

df = pd.DataFrame(np.arange(10).reshape(5,2),columns=list('AB'))
    A   B
0   0   1
1   2   3
2   4   5
3   6   7
4   8   9

我希望输出每一列 header 后跟像这样连接成字符串的列:

'''A
02468
B
13579'''

我可以用 for 循环这样做:

for col in df.columns:
  print(col, df[col].astype(str).str.cat(), sep='\n')

但是我有很多列 - 有没有更有效的方法来做到这一点?

尝试使用 astype 将列转换为 str,将它们连接在一起,然后利用 to_csv 创建格式化数据的能力,将分隔符设置为换行符,并排除 header:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(10).reshape(5, 2), columns=list('AB'))

s = df.astype(str).apply(''.join).to_csv(sep='\n', header=False)
print(s)

s:

A
02468
B
13579

我对时间很感兴趣,所以我制作了一个 perfplot:

import numpy as np
import pandas as pd
import perfplot


def make_data(n):
    if n // 2 == 0:
        return pd.DataFrame(columns=list('AB'))
    df = pd.DataFrame(np.arange(n).reshape(n // 2, 2), columns=list('AB'))
    return df


def for_option(df):
    s = ''
    for k, v in df.astype(str).to_dict('list').items():
        s += f"{k}\n{''.join(v)}\n"
    return s


def apply_option_to_csv(df):
    s = df.astype(str).apply(''.join).to_csv(sep='\n', header=False)
    return s


def apply_option_for(df):
    s = ''
    for k, v in zip(df.columns, df.astype(str).apply(''.join)):
        s += f"{k}\n{v}\n"
    return s


if __name__ == '__main__':
    out = perfplot.bench(
        setup=make_data,
        kernels=[
            for_option,
            apply_option_to_csv,
            apply_option_for
        ],
        labels=['for option', 'apply option (to csv)', 'apply option (for)'],
        n_range=[2 ** k for k in range(25)],
        equality_check=None
    )
    out.save('res.png', transparent=False)

看起来 to_csv 有一些开销,这使得它的整体效率低于其他选项。就 apply(''.join)to_dict('list').items() 和连接每个值而言,它们在较大值时表现相似,但 Scott Boston's solution 对于较小帧明显更快。

试试这个:

for k,v in df.astype(str).to_dict('list').items():
    print(k)
    print(''.join(v))

它可能比使用 df.apply 更快,您必须使用您的数据框进行测试。