2016-09-26 291 views
2

我是Python和Pandas的新手,我已經拉入了一個包含15個以上不同日期時間列的數據庫表。我的任務是通常按行中的最新值排序這些列。但是,數據並不乾淨。有時候,A列的日期會在第0行的B列日期之前出現,A會在第1行的B之後出現。如何在Pandas數據框中按行值對日期時間列進行排序?

我編寫了幾個函數(爲簡單起見,此處編輯)通過計算時間百分比在一個日期來之前和B之後,然後根據這個百分比排序的列:

def get_percentage(df, df_subset): 
    return len(df_subset)/float(len(df))  

def duration_report(df, earlier_column, later_column): 
    results = {} 
    td = df[later_column] - df[earlier_column] 
    results["Before"] = get_percentage(df, df.loc[td >= pd.Timedelta(0)]) 
    results["After"] = get_percentage(df, df.loc[td <= pd.Timedelta(0)]) 
    ind = "%s vs %s" % (earlier_column, later_column) 
    return pd.DataFrame(data=results, index=[ind]) 

def order_date_columns(df, col1, col2): 
    before = duration_report(df, col1, col2).Before.values[0] 
    after = duration_report(df, col1, col2).After.values[0] 
    if before >= after: 
     return [col1, col2] 
    else: 
     return [col2, col1] 

我與上面的代碼的目標是通過編程實現以下:

如果柱A日期到來在Col B日期爲50 +%的時間之前,Col A應該在t之前的Col B之前他列出了最早的日期時間列。

order_date_columns()函數成功排序兩列到正確的順序,但我怎麼一次將這個排序到15+列?我查看了df.apply()lambdamap(),但未能解決此問題。

任何幫助(與代碼的清晰度/效率),將不勝感激!

+0

爲了記錄,我使用了Anaconda的Python 2.7.12。 – alemosie

回答

1

由於您使用Python 2.7,你可以使用關鍵字cmp參數爲sorted。要得到列名的順序,你要尋找的,我會做這樣的事情:

# Returns -1 if first_column[i] > second_column[i] more often. 
# Returns 1 if vice versa. 
# Returns 0 if equal. 
# Assumes df[first_column] and df[second_column] are the same length. 
def compare_two(first_column, second_column): 
    c1_greater_count = 0 
    c2_greater_count = 0 
    # Iterate over the two columns in the dataframe. df must be in accessible scope. 
    for i in range(len(df[first_column])): 
     if df[first_column].iloc(i) > df[second_column].iloc[i]: 
      c1_greater_count += 1 
     elif df[second_column].iloc[i] > df[first_column].iloc[i]: 
      c2_greater_count += 1 

    if c1_greater_count > c2_greater_count: 
     return -1 
    if c2_greater_count > c1_greater_count: 
     return 1 
    return 0 

df = get_dataframe_from_somewhere() 
relevant_column_names = get_relevant_column_names(df) # e.g., get all the dates. 
sorted_column_names = sorted(relevant_column_names, cmp=compare_two) 

# sorted_column_names holds the names of the relevant columns, 
# sorted according to the given ordering. 

我敢肯定有一個更Python的方式來做到這一點,但這應該工作。請注意,對於Python 3,您可以使用cmp_to_key實用程序。

2

如果你不介意有點快捷方式,並使用每個日期列的中位數,這應該工作:

def order_date_columns(df, date_columns_to_sort): 
    x = [(col, df[col].astype(np.int64).median()) for col in date_columns_to_sort] 
    return [x[0] for x in sorted(x, key=lambda x: x[1])] 
+0

感謝!我將它應用於數據,輸出看起來基本正確,但是測試了我的一些假設;我將不得不進一步調查。這些數據中的日期非常時髦,因此我更喜歡逐步的基於百分比的方法。我仍然很想知道如何以「長」的方式做到這一點 - 更多的是將來應用於類似問題的做法! – alemosie

相關問題