我正在尝试写一些可以做的事情:
读取CSV记录,该记录具有1m行和100列以上的数据; 通过列出从最大到最小的重复行的出现来总结每一列
到目前为止我所拥有的:
import pandas as pd
df = pd.read_csv (r'infile.csv')
outfile = ('outfile.csv')
for i in df:
df.pivot_table(index=i, aggfunc='size').to_csv(outfile, mode='a')
此代码输出如下:
ColumnA,0
asdf,30
qwer,10
xyz,3
ColumnB,0
zxcv,50
jkl,8
我希望这样的输出在excel中打开:
ColumnA ColumnB
asdf 30 zxcv 50
qwer 10 jkl 8
xyz 3
或至少具有这样的CSV:
ColumnA
asdf,30
qwer,10
xyz,3
ColumnB
zxcv,50
jkl,8
我已经尝试过在for循环中的每次迭代之后写一个空行,但是无论出于何种原因,空行总是总是在文件末尾添加-我认为这与Pandas推送数据帧的方式有关到CSV?我不知道。
CSV不使用相同的列标题,也不使用相同的行值,也不可靠地使用相同的列数或行数,因此它必须能够基于CSV包含的内容来创建这些列表,而无需用户输入。
如果可能的话,在一次全部输出数据之前,我也不反对将每个数据子集添加到更大的数据框中。
我对Pandas完全陌生,并且只是Python的初学者,所以我不知道什么是使这项工作最好的方法。
感谢您的帮助!
答案 0 :(得分:0)
这是一种使您非常接近所需CSV输出的方法:
# create sample data
from io import StringIO
import pandas as pd
data = '''col_a, col_b, col_c
10, 20, 30
10, 21, 31
10, 21, 33
11, 22, 33
'''
df = pd.read_csv(StringIO(data), sep=', ', engine='python')
print(df)
col_a col_b col_c
0 10 20 30
1 10 21 31
2 10 21 33
3 11 22 33
第二,使用unstack()
重新调整数据框的形状(即,列标签变为行标签)。并通过level=0
(原始列标签)计数值的数量:
df = df.unstack().groupby(level=0).value_counts()
col_a 10 3
11 1
col_b 21 2
20 1
22 1
col_c 33 2
30 1
31 1
dtype: int64
最后,重置索引(行标签),使列标签有意义,然后进行排序:
df = (df.reset_index()
.rename(columns={'level_0': 'orig_col', 'level_1': 'orig_value', 0: 'num_occur'})
.sort_values('orig_value')
.sort_values('num_occur', ascending=False)
.sort_values('orig_col')
)
print(df)
orig_col orig_value num_occur
0 col_a 10 3
1 col_a 11 1
2 col_b 21 2
3 col_b 20 1
4 col_b 22 1
5 col_c 33 2
6 col_c 30 1
7 col_c 31 1
您可以将数据框的最新版本写入Excel。
答案 1 :(得分:0)
我将假设一列中的值是单一类型,并且一列中可以包含字符串,第二列中可以包含整数,等等。(如果不正确,则可以将所有内容都转换为字符串并使用第一个回应)。
# create test data -- different type for each column
from io import StringIO
import pandas as pd
data2 = '''col_a, col_b, col_c
10, 'x', '2019-12-29'
10, 'y', '2019-12-29'
10, 'z', '2019-12-30'
11, 'z', '2019-12-31'
'''
df2 = pd.read_csv(StringIO(data2), sep=', ', engine='python', parse_dates=['col_c'])
现在在每列上使用value_counts()
,并连接成一个宽表:
results = list()
for col in df2.columns:
s = (df2[col]
.value_counts()
.reset_index()
.rename(columns = {'index': 'value', col: 'count'}))
s.columns = pd.MultiIndex.from_product([[col], s.columns])
results.append(s)
results = pd.concat(results, axis=1)
print(results)
col_a col_b col_c
value count value count value count
0 10.0 3.0 'z' 2 2019-12-29 2
1 11.0 1.0 'y' 1 2019-12-31 1
2 NaN NaN 'x' 1 2019-12-30 1