2016-09-26 288 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

相关问题