什么是从只有很少行的csv文件填充数据框的pythonic方法?

时间:2016-10-26 04:56:15

标签: python python-2.7 pandas dataframe reindex

我有一个只有以下两行的csv文件:

ID    CODE       DATE        STARTDATE         AVERAGE1    AGGREGATE    MEDIAN1    MEDIAN2    AVERAGE2    AVERAGE3    POSITION
123    112     2016OCT25     2016OCT25         821          3              1021       4000       172         183          S8
124    111     2016OCT25     2016OCT25         834          3              1025       4210       173         185          ENG    

位置列采用S1-S8和T1-T8中的值(总共16个)。我想创建一个如下所示的数据框:

 AVERAGE1  MEDIAN1   MEDIAN2   AVERAGE2   AVERAGE3         POSITION                        
                                                                 S1

                                                                 S2

                                                                 S3

                                                                 S4

                                                                 S5

                                                                 S6

                                                                 S7

                                                                 S8

                                                                 T1

                                                                 T2

                                                                 T3

                                                                 T4

                                                                 T5

                                                                 T6

                                                                 T7

                                                                 T8

现在的问题是,如果csv文件中的“POSITION”列读取“ENG”,则必须从S1-T8填写数据帧中所有位置的列数据中相同的相应数据。如果它读取任何特定位置,例如上面第二列中的S8,则必须将csv中该列的数据填充到数据帧中的相应POSITION。为了更清楚,输出应如下所示:

 AVERAGE1     MEDIAN1     MEDIAN2     AVERAGE2      AVERAGE3    POSITION                        
    821          1021        4000       172           183        S1

    821          1021        4000       172           183        S2                                              

    821          1021        4000       172           183        S3                                                     

    821          1021        4000       172           183        S4  

    821          1021        4000       172           183        S5                                         

    821          1021        4000       172           183        S6                                                   

    821          1021        4000       172           183        S7                                                  

    834          1025        4210       173           185        S8                                                    

    821          1021        4000       172           183        T1                                                     

    821          1021        4000       172           183        T2

    821          1021        4000       172           183        T3

    821          1021        4000       172           183        T4

    821          1021        4000       172           183        T5

    821          1021        4000       172           183        T6

    821          1021        4000       172           183        T7

    821          1021        4000       172           183        T8

我通过创建一个空数据框完成了这个,然后在读取csv后用df.iloc填充了单元格。任何更有效或pythonic的方法将非常感激。提前谢谢!

1 个答案:

答案 0 :(得分:2)

我认为您可以pos使用reindexfillna使用ENG列中POSITION行的值,drop不必要的列,转为int和最后reset_index

pos = ['S' + str(x) for x in range(1, 9)] + ['T' + str(x) for x in range(1,9)] 
print (pos)
['S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 
 'T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8']

df.set_index('POSITION', inplace=True)
print (df.reindex(pos).fillna(df.ix['ENG']))
             ID   CODE       DATE  STARTDATE  AVERAGE1  AGGREGATE  MEDIAN1  \
POSITION                                                                     
S1        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S2        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S3        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S4        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S5        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S6        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S7        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
S8        123.0  112.0  2016OCT25  2016OCT25     821.0        3.0   1021.0   
T1        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T2        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T3        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T4        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T5        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T6        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T7        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   
T8        124.0  111.0  2016OCT25  2016OCT25     834.0        3.0   1025.0   

          MEDIAN2  AVERAGE2  AVERAGE3  
POSITION                               
S1         4210.0     173.0     185.0  
S2         4210.0     173.0     185.0  
S3         4210.0     173.0     185.0  
S4         4210.0     173.0     185.0  
S5         4210.0     173.0     185.0  
S6         4210.0     173.0     185.0  
S7         4210.0     173.0     185.0  
S8         4000.0     172.0     183.0  
T1         4210.0     173.0     185.0  
T2         4210.0     173.0     185.0  
T3         4210.0     173.0     185.0  
T4         4210.0     173.0     185.0  
T5         4210.0     173.0     185.0  
T6         4210.0     173.0     185.0  
T7         4210.0     173.0     185.0  
T8         4210.0     173.0     185.0  
df = df.reindex(pos)
       .fillna(df.ix['ENG'])
       .drop(['ID','CODE','DATE','STARTDATE'],axis=1)
       .astype(int)
       .reset_index()

print (df)
   POSITION  AVERAGE1  AGGREGATE  MEDIAN1  MEDIAN2  AVERAGE2  AVERAGE3
0        S1       834          3     1025     4210       173       185
1        S2       834          3     1025     4210       173       185
2        S3       834          3     1025     4210       173       185
3        S4       834          3     1025     4210       173       185
4        S5       834          3     1025     4210       173       185
5        S6       834          3     1025     4210       173       185
6        S7       834          3     1025     4210       173       185
7        S8       821          3     1021     4000       172       183
8        T1       834          3     1025     4210       173       185
9        T2       834          3     1025     4210       173       185
10       T3       834          3     1025     4210       173       185
11       T4       834          3     1025     4210       173       185
12       T5       834          3     1025     4210       173       185
13       T6       834          3     1025     4210       173       185
14       T7       834          3     1025     4210       173       185
15       T8       834          3     1025     4210       173       185

另一种解决方案:

df.set_index('POSITION', inplace=True)
#remove unnecessary columns
df = df.drop(['ID','CODE','DATE','STARTDATE'],axis=1)

#index values
pos = ['S' + str(x) for x in range(1, 9)] + ['T' + str(x) for x in range(1,9)] 
#DataFrame constructor
df1 = pd.DataFrame(data=[df.ix['ENG']], index=pos)
df1.index.name = 'POSITION'

#get all not ENG index values
not_eng_idx = df.drop('ENG').index
print (not_eng_idx)
Index(['S8'], dtype='object', name='POSITION')

#overwrite DataFrame by values from df
df1.ix[not_eng_idx] = df.ix[not_eng_idx]
df1.reset_index(inplace=True)
print (df1)
   POSITION  AVERAGE1  AGGREGATE  MEDIAN1  MEDIAN2  AVERAGE2  AVERAGE3
0        S1       834          3     1025     4210       173       185
1        S2       834          3     1025     4210       173       185
2        S3       834          3     1025     4210       173       185
3        S4       834          3     1025     4210       173       185
4        S5       834          3     1025     4210       173       185
5        S6       834          3     1025     4210       173       185
6        S7       834          3     1025     4210       173       185
7        S8       821          3     1021     4000       172       183
8        T1       834          3     1025     4210       173       185
9        T2       834          3     1025     4210       173       185
10       T3       834          3     1025     4210       173       185
11       T4       834          3     1025     4210       173       185
12       T5       834          3     1025     4210       173       185
13       T6       834          3     1025     4210       173       185
14       T7       834          3     1025     4210       173       185
15       T8       834          3     1025     4210       173       185