使用列名x值对读取csv

使用列名x值对读取csv,csv,pandas,dictionary,dataframe,import,Csv,Pandas,Dictionary,Dataframe,Import,我有一个带有“column name x value”对的长(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

我有一个带有“column name x value”对的长(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
我试图将它读入一个列表并从中创建一个数据帧,但是熊猫崩溃了,因为我有450万个元素


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

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

您可以创建数据结构(如dictionary)并使用它创建数据帧:

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
首次用于创建
数据帧

 df = pd.to_csv('file.csv')
然后需要:

另一个解决方案是,将
NaN
替换为
0
,最后一次转换为
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:索引包含重复项,无法重新格式化

这意味着您有一些重复项,因此最快的解决方案是使用
取消堆栈
和一些聚合函数,如
平均值
求和

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
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”,因为它是分类值,但通过首先查看已排序的表,然后只保留最后一个条目来解决问题。。。然后应用(很棒的!)解决方案。。我仍然需要完全理解;-)


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

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

哇,这已经是一个很酷的方法了,我已经好几天没找到了!问题是,我在取消堆栈时出错>“ValueError:索引包含重复条目,无法重塑”请参阅更新的解决方案,我尝试解释问题并获得解决方案。这是我几天内找不到的伟大解决方案!谢谢!谢谢,只有一个改进
df.sort(columns=(['user\u id','col'])
在旧版本的pandas中很好,在新版本的get
futurearning中警告:sort(columns=…)已被弃用,使用sort\u值(by=…)
,因此最好的方法是使用
df.sort\u值(['user\u id','col'],inplace=True)
必须更改df=df[df.duplicated(keep='last')]todf=df.drop_duplicates(keep='last'),现在我再次得到错误,尽管它删除了相当多的重复项。“ValueError:索引包含重复项,无法重塑”。。。奇怪看起来是个有趣的选择。在我的例子中,我不能使用“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)
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