2016-04-04 21 views
0

varsayalım iki dataframes:sırala dataframe satırlar

Ben dat2 satırları tarafından DAT1 en satırları sıralamak DAT1 sipariş veri alt kümesini ayıklamak istiyorum
import pandas as pd 
import numpy as np 

d1 = {} 
d2 = {} 

np.random.seed(5) 
for col in list("ABCDEF"): 
    d1[col] = np.random.randn(12) 
    d2[col+'2'] = np.random.random_integers(0,100, 12) 

t_index = pd.date_range(start = '2015-01-31', periods = 12, freq = "M") 

dat1 = pd.DataFrame(d1, index = t_index) 
dat2 = pd.DataFrame(d2, index = t_index) 

. Aşağıda, satır başına ilk 5 değerin dat1'den çıkarıldığı bir örnektir. Örneğin ile :

    A   B   C   D   E  F 
2015-01-31 0.441227 -0.817548 -0.723062 -0.205149 0.230843 -0.25395 
2015-02-28 -0.330870 -1.168279 -0.042419 -0.8 -0.042166 0.42985 

      A2 B2 C2 D2 E2 F2 
2015-01-31 47 47 82 66 64 40 
2015-02-28 30 16 60 57 77 74 

Ben alacağı:

  0 1 2 3 4 
2015-01-31 A B E D C 
2015-02-28 A D C F E 
        0   1   2   3   4 
2015-01-31 0.441227 -0.817548 0.230843 -0.205149 -0.723062 
2015-02-28 -0.330870 -0.8 -0.042419 0.429850 -0.042166 

İşte benim çözümdür. En büyük sorun, bu kodun dat1 veya dat2 cinsinden NA değerleri ile uğraşmamasıdır ki bu da düzeltilmesi gereken çok büyük bir sorundur.

def sortByAnthr(X,Y): 
    return([x for (x,y) in sorted(zip(X,Y), key=lambda pair: pair[1])]) 

def r_selectr(dat2,dat1, n): 
    ordr_cols = dat1.apply(lambda x: sortByAnthr(x.index,dat2.loc[x.name,:]),axis=1).iloc[:,-n:] 
    ordr_cols.columns = list(range(0,n)) #assign column names 

    ordr_r = ordr_cols.apply(lambda x: dat1.ix[x.name,x.values].tolist(),axis=1) 
    return([ordr_cols, ordr_r]) 

ordr_cols,ordr_r = r_selectr(dat2,dat1,5) 

ordr_cols.iloc[:2,:] 
      0 1 2 3 4 
2015-01-31 A B E D C 
2015-02-28 A D C F E 

ordr_r.iloc[:2,:] 
        0   1   2   3   4 
2015-01-31 0.441227 -0.817548 0.230843 -0.205149 -0.723062 
2015-02-28 -0.330870 -0.8 -0.042419 0.429850 -0.042166 

Örneğin, UA'lara ile yukarıda doğru sıralamak için başarısız:

dat1.iloc[[1,2],[1,3,5]]=np.nan 
dat2.iloc[[1,4],[2,4,5]]=np.nan 

cevap

0

İşte benim çözümdür. Şimdi NA'ları, NA olmayan değerlerin indekslerini dat1 ve dat2'de her satır için kesiştirerek işler. Bununla birlikte, bu, başvuruda, her bir satır için aynı büyüklükteki çıktıya ihtiyaç duyan bir konu ortaya koymaktadır. Sıralanamayan/düzenlenmeyen öğeleri dolduran işlev fillVacuum'dur.

dat1.iloc[:2,:] 
        A   B   C   D   E   F 
2015-01-31 0.441227 -0.817548 -0.723062 -0.205149 0.230843 -0.253954 
2015-02-28  NaN  NaN -0.042419 -0.8  NaN 0.429850 

dat2.iloc[:2,:] 
      A2 B2 C2 D2 E2 F2 
2015-01-31 47 47 82 66 64 40 
2015-02-28 NaN 16 60 57 77 NaN 

ordr_cols.iloc[:2,:] 
       0 1 2 3 4 
2015-01-31 A B E D C 
2015-02-28 NaN NaN NaN D C 

ordr_r.iloc[:2,:] 
        0   1   2   3   4 
2015-01-31 0.441227 -0.817548 0.230843 -0.205149 -0.723062 
2015-02-28  NaN  NaN  NaN -0.8 -0.042419 
:

def fillVacuum(toFill,MatchLengthOf): 
    if len(toFill)<len(MatchLengthOf): 
     [toFill.insert(i, np.nan) for i in range(len(MatchLengthOf)-len(toFill))] 
    return() 

def sortByAnthr(X,Y,Xindex): 
    #intersect non-na column indexes between two datasets 
    idx = np.intersect1d(X.notnull().nonzero()[0],Y.notnull().nonzero()[0]) 

    #order the subset of X.index by Y 
    ordrX = [x for (x,y) in sorted(zip(Xindex[idx],Y[idx]), key=lambda pair: pair[1])] 

    #due to molding that'll happen later in apply, it is necessary to fill removed indexes 
    fillVacuum(ordrX, Xindex) 

    return(ordrX) 

def OrderRow(row,df): 
    ordrd_row = df.ix[row.dropna().name,row.dropna().values].tolist() 
    fillVacuum(ordrd_row, row) 
    return(ordrd_row) 

def r_selectr(dat2,dat1, n): 
    ordr_cols = dat1.apply(lambda x: sortByAnthr(x,dat2.loc[x.name,:],x.index),axis=1).iloc[:,-n:] 
    ordr_cols.columns = list(range(0,n)) #assign interpretable column names 

    ordr_r = ordr_cols.apply(lambda x: OrderRow(x,dat1),axis=1) 
    return([ordr_cols, ordr_r]) 

ordr_cols,ordr_r = r_selectr(dat2,dat1,5) 

Bu işlevler aşağıdaki verim