需要通过使用随机列读取csv文件来创建Pandas数据帧

时间:2016-09-22 21:05:24

标签: python csv pandas

我有以下带有记录的csv文件:

  • A 1,B 2,C 10,D 15
  • A 5,D 10,G 2
  • D 6,E 7
  • H 7,G 8

我的列标题/名称是:A,B,C,D,E,F,G

因此,使用“read_csv”后的初始数据帧变为:

A     B     C      D       E      F      G   
A 1   B 2   C 10   D 15   NaN    NaN    NaN
A 5   D 10  G 2    NaN    NaN    NaN    NaN
D 6   E 7   NaN    NaN    NaN    NaN    NaN
H 7   G 8   NaN    NaN    NaN    NaN    Nan

该值可以分为[列名] [列值],因此A 1表示col = A且值= 1,D 15表示col = D且值= 15等...

我想要的是根据数据将数值分配给相应的列 并有一个如下所示的数据框:

A     B     C      D       E      F      G   
A 1   B 2   C 10   D 15   NaN    NaN    NaN
A 5   Nan   NaN    D 10   NaN    NaN    G 2
NaN   NaN   NaN    D 6    E 7    NaN    NaN
NaN   NaN   NaN    NaN    NaN    NaN    G 8

更好的是,仅仅是价值观:

A     B     C      D       E      F      G   
1     2     10     15      NaN    NaN    NaN
5     Nan   NaN    10      NaN    NaN    2
NaN   NaN   NaN    6       7      NaN    NaN
NaN   NaN   NaN    NaN     NaN    NaN    8

3 个答案:

答案 0 :(得分:2)

您可以使用apply函数(axis = 1)遍历行,并根据拆分后的键值对为每行构建一个pandas系列,新构建的系列将自动对齐他们的索引,只是注意这里没有F列,而是额外的H,不确定它是否是你需要的。但是,删除H并添加额外的NaN F列应该是直截了当的:

df.apply(lambda r: pd.Series({x[0]: x[1] for x in r.str.split(' ') 
                                    if isinstance(x, list) and len(x) == 2}), axis = 1)


#     A   B   C   D   E   G   H
#0    1   2  10  15 NaN NaN NaN
#1    5 NaN NaN  10 NaN   2 NaN
#2  NaN NaN NaN   6   7 NaN NaN
#3  NaN NaN NaN NaN NaN   8   7

答案 1 :(得分:2)

应用解决方案:

按空格使用split,按dropna移除NaN行,set_index并将DataFrame列转换为Series {{3} }}。新列名称的上一个DataFrame.squeeze

print (df.apply(lambda x: x.str.split(expand=True)
                               .dropna()
                               .set_index(0)
                               .squeeze(), axis=1)
         .reindex(columns=list('ABCDEFGH')))

     A    B    C    D    E   F    G    H
0    1    2   10   15  NaN NaN  NaN  NaN
1    5  NaN  NaN   10  NaN NaN    2  NaN
2  NaN  NaN  NaN    6    7 NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN NaN    8    7

Stack 解决方案:

使用reindex按空格创建Seriesstack并创建新列,使用新列名添加列(AB ... )splitindex,按set_index将一列DataFrame转换为Series,用DataFrame.squeeze删除旧列名的索引值,{ {3}},reset_index新列名称(添加NaN填充的缺失列),unstack将值转换为float,最后按{{删除列名称3}}(pandas 0.18.0中的新内容):

print (df.stack()
         .str.split(expand=True)
         .set_index(0, append=True)
         .squeeze()
         .reset_index(level=1, drop=True)
         .unstack()
         .reindex(columns=list('ABCDEFGH'))
         .astype(float)
         .rename_axis(None, axis=1))

     A    B     C     D    E   F    G    H
0  1.0  2.0  10.0  15.0  NaN NaN  NaN  NaN
1  5.0  NaN   NaN  10.0  NaN NaN  2.0  NaN
2  NaN  NaN   NaN   6.0  7.0 NaN  NaN  NaN
3  NaN  NaN   NaN   NaN  NaN NaN  8.0  7.0

答案 2 :(得分:0)

以下是代码:

brew tap homebrew/nginx
brew install nginx-full --with-realip

输入:

res = pd.DataFrame(index=df.index, columns=list('ABCDEFGH'))

def classifier(row):
    cols = row.str.split().str[0].dropna().tolist()
    vals = row.str.split().str[1].dropna().tolist()
    res.loc[row.name, cols] = vals

df.apply(classifier, axis=1)

输出:

from io import StringIO
import pandas as pd
import numpy as np

data = """A 1, B 2, C 10, D 15
A 5, D 10, G 2
D 6, E 7
H 7, G 8"""

df = pd.read_csv(StringIO(data), header=None)
print("df:\n", df)

res = pd.DataFrame(index=df.index, columns=list('ABCDEFGH'))

def classifier(row):
    cols = row.str.split().str[0].dropna().tolist()
    vals = row.str.split().str[1].dropna().tolist()
    res.loc[row.name, cols] = vals
df.apply(classifier, axis=1)

print("\nres:\n", res)