Python 如何在数据帧中按行值对日期时间列进行排序?

Python 如何在数据帧中按行值对日期时间列进行排序?,python,python-2.7,sorting,datetime,pandas,Python,Python 2.7,Sorting,Datetime,Pandas,我是Python和Pandas的新手,我引入了一个包含15个以上不同datetime列的数据库表。我的任务是按照行中最早到最晚的值对这些列进行排序。然而,数据并不干净;有时,第0行中A列的日期在B列的日期之前,第1行中A列的日期在B列的日期之后 我编写了几个函数(为了简单起见,在这里进行了编辑),通过计算a中日期在B之前和之后出现的时间百分比来比较两列,然后根据该百分比对列进行排序: def get_percentage(df, df_subset): return len(df_sub

我是Python和Pandas的新手,我引入了一个包含15个以上不同datetime列的数据库表。我的任务是按照行中最早到最晚的值对这些列进行排序。然而,数据并不干净;有时,第0行中A列的日期在B列的日期之前,第1行中A列的日期在B列的日期之后

我编写了几个函数(为了简单起见,在这里进行了编辑),通过计算a中日期在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]
def get_百分比(df,df_子集):
返回len(df_子集)/float(len(df))
def持续时间报告(df、前一列、后一列):
结果={}
td=df[后面的列]-df[前面的列]
结果[“在”]=获取百分比(df,df.loc[td>=pd.Timedelta(0)])
结果[“之后”]=获得百分比(df,df.loc[td=之后:
返回[col1,col2]
其他:
返回[col2,col1]
我使用上述代码的目标是以编程方式实现以下内容:

如果A列日期在B列日期之前的时间超过50%,则在最早到最晚的日期时间列列表中,A列应在B列之前

order\u date\u columns()
函数成功地将两列排序为正确的顺序,但是如何将此排序同时应用于15+列?我已经研究了
df.apply()
lambda
map()
,但未能解决此问题


任何帮助(代码清晰/高效)都将不胜感激!

如果您不介意走一点捷径并使用每个日期列的中间值,这应该可以:

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])]

由于您使用的是Python 2.7,因此可以使用
cmp
关键字参数对
进行排序

# 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,您可以使用该实用程序。

谢谢!我将其应用于数据,输出看起来基本正确,但测试了我的一些假设;我将不得不进一步研究。这些数据中的日期非常有趣,因此我感到更舒服我仍然很想知道如何在“漫长”的过程中做到这一点——更多的是作为一种实践来应用于将来的类似问题!作为记录,我使用的是Anaconda的Python 2.7.12。