将 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
更快,您必须使用您的数据框进行测试。
假设我有以下 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
更快,您必须使用您的数据框进行测试。