【问题标题】:compare string against tuples in list of tuples - python将字符串与元组列表中的元组进行比较 - python
【发布时间】:2021-02-17 23:15:05
【问题描述】:

尝试创建具有适当纳税年度的新列 Tax_Year,通过检查 date 列中的日期时间是否在个人 txYear_ 的元组元素的边界内形成...

salesReport  = pd.DataFrame({'date': ['2017-07-02 09:00:00', '2017-07-03 15:00:00', '2018-04-05 15:00:00', 
                                    '2018-12-20 11:00:00', '2019-01-06 14:00:00', '2020-09-06 17:00:00'], 
                            'sales': [100, 339, 98, 1020, 630, 765]})

txYear_0304 = (dt.datetime(2003, 4, 6), dt.datetime(2004, 4, 5))
txYear_0405 = (dt.datetime(2004, 4, 6), dt.datetime(2005, 4, 5))
txYear_0506 = (dt.datetime(2005, 4, 6), dt.datetime(2006, 4, 5))
txYear_0607 = (dt.datetime(2006, 4, 6), dt.datetime(2007, 4, 5))
txYear_0708 = (dt.datetime(2007, 4, 6), dt.datetime(2008, 4, 5))
txYear_0809 = (dt.datetime(2008, 4, 6), dt.datetime(2009, 4, 5))
txYear_0910 = (dt.datetime(2009, 4, 6), dt.datetime(2010, 4, 5))
txYear_1011 = (dt.datetime(2010, 4, 6), dt.datetime(2011, 4, 5))
txYear_1112 = (dt.datetime(2011, 4, 6), dt.datetime(2012, 4, 5))
txYear_1213 = (dt.datetime(2012, 4, 6), dt.datetime(2013, 4, 5))
txYear_1314 = (dt.datetime(2013, 4, 6), dt.datetime(2014, 4, 5))
txYear_1415 = (dt.datetime(2014, 4, 6), dt.datetime(2015, 4, 5))
txYear_1516 = (dt.datetime(2015, 4, 6), dt.datetime(2016, 4, 5))
txYear_1617 = (dt.datetime(2016, 4, 6), dt.datetime(2017, 4, 5))
txYear_1718 = (dt.datetime(2017, 4, 6), dt.datetime(2018, 4, 5))
txYear_1819 = (dt.datetime(2018, 4, 6), dt.datetime(2019, 4, 5))
txYear_1920 = (dt.datetime(2019, 4, 6), dt.datetime(2020, 4, 5))
txYear_2021 = (dt.datetime(2020, 4, 6), dt.datetime(2021, 4, 5))

tax_year = [txYear_0304, txYear_0405, txYear_0506, txYear_0607, txYear_0708, txYear_0809, txYear_0910, txYear_1011, txYear_1112, 
            txYear_1213, txYear_1314, txYear_1415, txYear_1516, txYear_1617, txYear_1718, txYear_1819, txYear_1920,  txYear_2021]

当满足这个条件时,我希望变量名出现在新列的相应行中

举例

                  date  sales      Tax_Year
0  2017-07-02 09:00:00    100   txYear_1617  
1  2017-07-03 15:00:00    339   txYear_1617
2  2018-04-05 15:00:00     98   txYear_1718 
3  2018-12-20 11:00:00   1020   txYear_1819
4  2019-01-06 14:00:00    630   txYear_1819
5  2020-09-06 17:00:00    765   txYear_2021

我已经使用np.where....解决了这个问题。

salesReport['Tax_Year'] = np.where(tax_year[0] <= salesReport['date'] and tax_year[1] >= salesReport['date'], tax_year, np.nan)

但是,我无法解决收到的错误...

TypeError: '>=' not supported between instances of 'str' and 'tuple'

此外,我也不确定如何获取变量名,因为目前我将返回不是我想要的实际元组内容

【问题讨论】:

  • 在我继续查看您的代码时作为提示:您可以链接比较运算符,这极大地提高了可读性:a &lt; x &lt; b 或在您的情况下,ty[0] &lt;= sr &lt;= ty[1]
  • 我认为问题在于您在 DataFrame 中的时间戳不是日期时间对象。虽然我并没有真正使用 Pandas,而且我一直认为这是自动的,但看起来这可能正在发生。
  • 根据您的评论,我更改了格式...salesReport['date'] = pd.to_datetime(salesReport['date']) 但现在错误为ValueError: Lengths must match
  • 对,所以我相信这是由于您尝试传入日期时间元组列表,但 np.where 需要一个布尔条件检查。但您似乎想要检查所有纳税年度。
  • 是的,我需要检查所有纳税年度。所以np.where 不是最好的方法吗?

标签: python pandas numpy tuples


【解决方案1】:

免责声明:

我不精通 Pandas。如果有更好的方法来做到这一点,我不会感到惊讶。

我已将tax_years 元组列表转换为字典,并定义了一个独立函数来获取给定日期时间对象的纳税年度。实际上,我并不是 100% 知道纳税年度的结束/开始时间,因此比较仅在 MM-DD-YY 上进行,并从数据框中存在的时间戳中删除时间。

import pandas as pd
import numpy as np
import datetime

tax_years = {
    (datetime.datetime(2003, 4, 6), datetime.datetime(2004, 4, 5)): "TY0304",
    (datetime.datetime(2004, 4, 6), datetime.datetime(2005, 4, 5)): "TY0405",
    (datetime.datetime(2005, 4, 6), datetime.datetime(2006, 4, 5)): "TY0506",
    (datetime.datetime(2006, 4, 6), datetime.datetime(2007, 4, 5)): "TY0607",
    (datetime.datetime(2007, 4, 6), datetime.datetime(2008, 4, 5)): "TY0708",
    (datetime.datetime(2008, 4, 6), datetime.datetime(2009, 4, 5)): "TY0809",
    (datetime.datetime(2009, 4, 6), datetime.datetime(2010, 4, 5)): "TY0910",
    (datetime.datetime(2010, 4, 6), datetime.datetime(2011, 4, 5)): "TY1011",
    (datetime.datetime(2011, 4, 6), datetime.datetime(2012, 4, 5)): "TY1112",
    (datetime.datetime(2012, 4, 6), datetime.datetime(2013, 4, 5)): "TY1213",
    (datetime.datetime(2013, 4, 6), datetime.datetime(2014, 4, 5)): "TY1314",
    (datetime.datetime(2014, 4, 6), datetime.datetime(2015, 4, 5)): "TY1415",
    (datetime.datetime(2015, 4, 6), datetime.datetime(2016, 4, 5)): "TY1516",
    (datetime.datetime(2016, 4, 6), datetime.datetime(2017, 4, 5)): "TY1617",
    (datetime.datetime(2017, 4, 6), datetime.datetime(2018, 4, 5)): "TY1718",
    (datetime.datetime(2018, 4, 6), datetime.datetime(2019, 4, 5)): "TY1819",
    (datetime.datetime(2019, 4, 6), datetime.datetime(2020, 4, 5)): "TY1920",
    (datetime.datetime(2020, 4, 6), datetime.datetime(2021, 4, 5)): "TY2021"
}

salesReport  = pd.DataFrame({'date': ['2017-07-02 09:00:00',
                                      '2017-07-03 15:00:00',
                                      '2018-04-05 15:00:00',
                                      '2018-12-20 11:00:00',
                                      '2019-01-06 14:00:00',
                                      '2020-09-06 17:00:00'], 
                            'sales': [100, 339, 98, 1020, 630, 765]})

salesReport["date"] = pd.to_datetime(salesReport["date"])


def get_tax_year(date):
    for (start, end), tax_year in tax_years.items():
        if start.date() <= date.date() <= end.date():
            return tax_year
    return "null"


salesReport["tax_year"] = [get_tax_year(date) for date in salesReport["date"]]
print(salesReport)

还有输出:

                 date  sales tax_year
0 2017-07-02 09:00:00    100   TY1718
1 2017-07-03 15:00:00    339   TY1718
2 2018-04-05 15:00:00     98   TY1718
3 2018-12-20 11:00:00   1020   TY1819
4 2019-01-06 14:00:00    630   TY1819
5 2020-09-06 17:00:00    765   TY2021

【讨论】:

  • 再一次,我现在已经超出了我的舒适区:我很少使用 Pandas。我想这可能有一个很好的解决方案,但我现在不知道。我会继续研究,因为无论如何我都应该学习 Pandas。随着我的进步,我会更新我的帖子。
  • 您的努力得到了极大的赞赏,并给了我一些思考的余地。谢谢
  • 你是明星!!最终产品就在现场!!
  • 很高兴能帮上忙。我确信有更好的使用 Pandas 的方法,但最终使用本质上纯 Python 的方法很简单。
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 2019-05-02
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多