读取具有列名x值对的csv

时间:2017-02-19 12:44:19

标签: csv pandas dictionary dataframe import

我有一个带有“列名x值”对的长(csv)文件,我想将其读入pandas.DataFrame

user_id   col  val
00008901    1   55
00008901    2   66
00011501    1   77
00011501    3   88
00011501    4   99

结果应如下所示:

             1   2    3   4
00008901    55  66    0   0
00011501    77   0   88  99

我尝试将其读入列表并从中创建一个DataFrame,但是pandas因为我有450万个元素而崩溃。

最好的方法是什么?理想情况下直接使用read_csv。

3 个答案:

答案 0 :(得分:1)

首先使用read_csv创建DataFrame

 df = pd.to_csv('file.csv')

然后set_index需要unstack

df1 = df.set_index(['user_id','col'])['val'].unstack(fill_value=0)
print (df1)
col       1   2   3   4
user_id                
8901     55  66   0   0
11501    77   0  88  99

使用pivot的另一个解决方案,将NaN替换为0 fillna,最后转换为int

df1 = df.pivot(index='user_id', columns='col', values='val').fillna(0).astype(int)
print (df1)
col       1   2   3   4
user_id                
8901     55  66   0   0
11501    77   0  88  99

如果收到错误:

  

" ValueError:索引包含重复的条目,无法重构"

这意味着您有一些重复项,因此最快的解决方案是groupby unstack和一些聚合函数,如meansum

print (df.groupby(['user_id','col'])['val'].mean().unstack(fill_value=0))
col       1   2   3   4
user_id                
8901     55  66   0   0
11501    77   0  88  99

更好地看到有点改变csv

print (df)
   user_id  col  val
0     8901    1   55
1     8901    2   66
2    11501    1   77 > duplicates -> 11501 and 1
3    11501    1  151 > duplicates -> 11501 and 1
4    11501    3   88
5    11501    4   99


print (df.groupby(['user_id','col'])['val'].mean().unstack(fill_value=0))
col        1   2   3   4
user_id                 
8901      55  66   0   0
11501    114   0  88  99

其实我觉得我没有重复,但发现我真的有一些...... 我无法使用" .mean"因为它是分类值,但是通过首先查看已排序的表然后只保留最后一个条目来解决问题...然后应用(伟大的!)解决方案......我仍然需要完全理解; - )

df.sort(columns=(['user_id','col']) ) # optional for debugging
df.drop_duplicates(subset=['user_id','col'], keep='last', inplace=True)
df_table = df.set_index(['user_id','col'])['val'].unstack(fill_value=0)

答案 1 :(得分:1)

您无法使用read_csv直接读取所需的结构。但您可以使用pivot_table函数转换为所需的结构。

df = pd.read_csv('filepath/your.csv')
df = pd.pivot_table(df, index='user_id', columns='col', values='val, aggfunc='mean').reset_index()

The output will be like
             1   2    3   4
00008901    55  66    0   0
00011501    77   0   88  99

答案 2 :(得分:0)

我认为不可能使用read_csv来解析csv文件。

您可以创建数据结构(如字典)并使用它来创建数据框:

import pandas as pd
from collections import defaultdict
import csv

data_dict = defaultdict(lambda: [0] * columns)
columns = 4
delimiter = ','

with open("my_csv.csv") as csv_file:
    reader = csv.DictReader(csv_file,delimiter=delimiter)
    for row in reader:
        row_id = row["user_id"]
        col = int(row["col"])-1
        val = int(row["val"])
        data_dict[row_id][col] = val

df = pd.DataFrame(data_dict.values(), index=data_dict.keys(), columns=range(1, columns+1))

对于包含以下内容的csv文件:

user_id,col,val
00008901,1,55
00008901,2,66
00011501,1,77
00011501,3,88
00011501,4,99

输出结果为:

           1   2   3   4
00008901  55  66   0   0
00011501  77   0  88  99