Pandas-df.loc-只能比较标签相同的系列

时间:2019-04-17 21:26:44

标签: python pandas

我在下面的代码(抱歉,我无法共享确切的数据)采用df,按日期范围对其进行过滤,然后重新标记某些日期。然后,我想将这些重新标记的日期拖入原始df中。直到以下代码行都可以正常工作:

finaldf.loc[(finaldf['Due_Date'] != finaldfmon['Due_Date']), 'Due_Date'] = finaldfmon['Due_Date']

从现在的研究来看,这是因为索引长度不同。

print(finaldf.index)

vs

print(finaldfmon.index)

我不明白为什么这将是一个问题,也不知道如何解决。我想模拟一个excel vlookup,但如果未命中它们,则不会留下#NA(如Anchor值(认为主键)没有任何匹配项(外键)。

完整代码在这里:

    import pandas as pd
    import xlrd # added when using visual studio 
    import datetime
    from datetime import datetime
    finaldf = pd.read_excel("scrubcomplete.xlsx", encoding = "ISO-8859-1", dtype=object)
    finaldf.columns = finaldf.columns.str.strip().str.replace(' ', '_').str.replace('(', '').str.replace(')', '')
    #
    today = pd.to_datetime(datetime.now().date())
    day_of_week = today.dayofweek
    last_monday = today - pd.to_timedelta(day_of_week, unit='d') 
    finaldf = finaldf[finaldf.Affliate_Code.str.contains('Part/Unix', na=False)]

f day_of_week !=0:
    finaldf['Completed_Date'] = pd.to_datetime(finaldf['Completed_Date'], format="%m/%d/%Y").dt.date
    finaldf['Due_Date'] = pd.to_datetime(finaldf['Due_Date'], format="%m/%d/%y").dt.date # making it lower case y made it work 
    current_week_flags = (finaldf.Completed_Date >= last_monday.date()) & (finaldf.Completed_Date <= today.date()) # this worked as of 4.16
    earlydue = (finaldf.Due_Date < last_monday.date())
    flags = current_week_flags & earlydue
    finaldfmon = finaldf[current_week_flags]
    finaldfmon.loc[(finaldfmon['Due_Date']<last_monday.date()), 'Due_Date'] = last_monday # here we make all the due dates before monday, monday while complete date filterered
    finaldf.loc[(finaldf['Due_Date'] != finaldfmon['Due_Date']), 'Due_Date'] = 
    finaldfmon['Due_Date'] 
    writer = pd.ExcelWriter('currentweek.xlsx', engine='xlsxwriter')
    finaldf.to_excel(writer, index=False, sheet_name='Sheet1')    
    writer.save()

错误是:

  raise ValueError("Can only compare identically-labeled "
ValueError: Can only compare identically-labeled Series objects

原因是:

finaldf.loc[(finaldf['Due_Date'] != finaldfmon['Due_Date']), 'Due_Date'] = finaldfmon['Due_Date']

1 个答案:

答案 0 :(得分:1)

这不是答案,请参见代码中的注释。另外,在这一点上,我认为这个问题更适合codereview

finaldf['Completed_Date'] = pd.to_datetime(finaldf['Completed_Date'], format="%m/%d/%Y").dt.date

# making it lower case y made it work 
finaldf['Due_Date'] = pd.to_datetime(finaldf['Due_Date'], format="%m/%d/%y").dt.date 

# this worked as of 4.16
current_week_flags = (finaldf.Completed_Date >= last_monday.date()) & (finaldf.Completed_Date <= today.date()) 
earlydue = (finaldf.Due_Date < last_monday.date())

flags = current_week_flags & earlydue
finaldfmon = finaldf[current_week_flags]

# here we make all the due dates before monday, monday while complete date filterered
# this works because last_monday is a single day
finaldfmon.loc[(finaldfmon['Due_Date']<last_monday.date()), 'Due_Date'] = last_monday 

# this fails in two places:
# finaldf.loc[(finaldf['Due_Date'] != finaldfmon['Due_Date']), 'Due_Date'] = finaldfmon['Due_Date'] 

# finaldf['Due_Date'] != finaldfmon['Due_Date'] 
# these two series have different length, so you can't compare them 
# even if they have the same length, they have different indices
# (unless one of them is a single number/date, then it becomes the case above)

# finaldf.loc[..., 'Due_Date'] = finaldfmon['Due_Date']
# same story    

writer = pd.ExcelWriter('currentweek.xlsx', engine='xlsxwriter')
finaldf.to_excel(writer, index=False, sheet_name='Sheet1')    
writer.save()

下面的代码(主要是最后一行达到目标

import pandas as pd
import xlrd # added when using visual studio 
import datetime
from datetime import datetime
#read in excel file
finaldf = pd.read_excel("scrubcomplete.xlsx", encoding = "ISO-8859-1", dtype=object)
finaldf.columns = finaldf.columns.str.strip().str.replace(' ', '_').str.replace('(', '').str.replace(')', '')
#
today = pd.to_datetime(datetime.now().date())
day_of_week = today.dayofweek
last_monday = today - pd.to_timedelta(day_of_week, unit='d') 
#


if day_of_week !=0:
    finaldf['Completed_Date'] = pd.to_datetime(finaldf['Completed_Date'], format="%m/%d/%Y").dt.date
    finaldf['Due_Date'] = pd.to_datetime(finaldf['Due_Date'], format="%m/%d/%y").dt.date # making it lower case y made it work
    current_week_flags = (finaldf.Completed_Date >= last_monday.date()) & (finaldf.Completed_Date <= today.date())
    finaldf.loc[(finaldf['Completed_Date'] >= last_monday.date()) & (finaldf['Completed_Date'] <= today.date()) & (finaldf['Due_Date'] < last_monday.date()), 'Due_Date'] = last_monday