【问题标题】:"The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()." when applying function to a dataframe“Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。”将函数应用于数据框时
【发布时间】:2021-12-31 04:54:11
【问题描述】:

我有两个数据框 df1subdf

df1 看起来像这样:

from pandas import Timestamp, Timedelta
df = pd.DataFrame({'station_key': {1300234: 'CV000011', 1300235: 'CV000011'},'charger_key': {1300234: 'CV00001101', 1300235: 'CV00001101'},'cid': {1300234: '01', 1300235: '01'},'x': {1300234: '33.489125', 1300235: '33.489125'},'y': {1300234: '126.487631', 1300235: '126.487631'},'snm': {1300234: '에코티엘(제주)', 1300235: '에코티엘(제주)'},'addr': {1300234: '제주특별자치도 제주시 연동 251-69외 ',1300235: '제주특별자치도 제주시 연동 251-69외 '},'addr_jibun': {1300234: '-', 1300235: '-'},'started_at': {1300234: Timestamp('2020-11-03 20:56:31'),1300235: Timestamp('2020-11-03 23:10:12')},'ended_at': {1300234: Timestamp('2020-11-03 23:10:12'),1300235: Timestamp('2020-11-03 23:40:12')},'status': {1300234: '2', 1300235: '1'},'day': {1300234: 'Tuesday', 1300235: 'Tuesday'},'time_usage': {1300234: Timedelta('0 days 02:13:41'),1300235: Timedelta('0 days 00:30:00')},'start': {1300234: Timestamp('2020-11-03 00:00:00'),1300235: Timestamp('2020-11-03 00:00:00')},'end': {1300234: Timestamp('2020-11-03 00:00:00'),1300235: Timestamp('2020-11-03 00:00:00')},'start_hour': {1300234: 20, 1300235: 23},'end_hour': {1300234: 23, 1300235: 23},'start_minute': {1300234: 56, 1300235: 10},'end_minute': {1300234: 10, 1300235: 40}})

subdf 看起来像这样:

subdf = pd.DataFrame({'start': {1300234: Timestamp('2020-11-03 00:00:00'),4849001: Timestamp('2020-11-03 00:00:00')},'station_key': {1300234: 'CV000011', 4849001: 'CV000271'},'charger_key': {1300234: 'CV00001101', 4849001: 'CV00027101'},'cid': {1300234: '01', 4849001: '01'},'x': {1300234: '33.489125', 4849001: '33.452903'},'y': {1300234: '126.487631', 4849001: '126.572552'},'snm': {1300234: '에코티엘(제주)', 4849001: '제주첨단과학단지(엘리트빌딩)'},'0_occupation': {1300234: 0, 4849001: 0},'1_occupation': {1300234: 0, 4849001: 0},'2_occupation': {1300234: 0, 4849001: 0},'3_occupation': {1300234: 0, 4849001: 0},'4_occupation': {1300234: 0, 4849001: 0},'5_occupation': {1300234: 0, 4849001: 0},'6_occupation': {1300234: 0, 4849001: 0},'7_occupation': {1300234: 0, 4849001: 0},'8_occupation': {1300234: 0, 4849001: 0},'9_occupation': {1300234: 0, 4849001: 0},'10_occupation': {1300234: 0, 4849001: 0},'11_occupation': {1300234: 0, 4849001: 0},'12_occupation': {1300234: 0, 4849001: 0},'13_occupation': {1300234: 0, 4849001: 0},'14_occupation': {1300234: 0, 4849001: 0},'15_occupation': {1300234: 0, 4849001: 0},'16_occupation': {1300234: 0, 4849001: 0},'17_occupation': {1300234: 0, 4849001: 0},'18_occupation': {1300234: 0, 4849001: 0},'19_occupation': {1300234: 0, 4849001: 0},'20_occupation': {1300234: 0, 4849001: 0},'21_occupation': {1300234: 0, 4849001: 0},'22_occupation': {1300234: 0, 4849001: 0},'23_occupation': {1300234: 0, 4849001: 0}})

_occupation 列代表小时,因此有 24 列,范围从 0_occupation23_occupation

我尝试应用到df1 的功能如下:

def time_add(x):
    s_date = x['start']
    e_date = x['end']
    s_hour = x['start_hour']
    e_hour = x['end_hour']
    s_min = x['start_minute']
    e_min = x['end_minute']
    if(s_date == e_date):
        first_range = list(range(s_hour+1, e_hour))
        subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date), str(s_hour)+"_occupation"]+=((60 - s_min)/60)*100
        for i in first_range:
            subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date), str(i)+"_occupation"] = 1
        subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date), str(e_hour)+"_occupation"]+=(e_min/60)*100
    else:
        first_range = list(range(s_hour+1, 24))
        subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date), str(s_hour)+"_occupation"]+=((60 - s_min)/60)*100
        for i in first_range:
            subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date), str(i)+"_occupation"] = 1
        second_range = list(range(0, e_hour))
        for i in second_range:
            subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date+1), str(i)+"_occupation"] = 1
        subdf.loc[(subdf["charger_key"] == x['charger_key']) & (subdf["start"] == s_date+1), str(e_hour)+"_occupation"]+=(e_min/60)*100

但是,当我尝试通过执行 time_add(df1) 来应用此功能时,会引发错误:

The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

我查看了这个,当使用 andor 而不是 &| 时似乎会发生此错误,但在我的函数中并非如此。

错误的完整回溯如下

提前谢谢你!!

【问题讨论】:

  • 能否请您添加错误的完整回溯?
  • 发布了完整的回溯!

标签: python pandas dataframe function datetime


【解决方案1】:

在这一行:

if(s_date == e_date):

s_datee_date 变量不是单个值,而是 Pandas 数据框中的整个列。当你比较它们时,这意味着什么?您想检查一列中的 所有 值是否等于另一列?或者你想检查至少一个值是否等于对应的值?或者你想根据这两列中的对应值是否相等对行做不同的事情?

if (s_date == e_date).all():
    # True if ALL values are equal.

或者,

if (s_date == e_date).any():
    # True if AT LEAST ONE value is equal.

【讨论】:

  • 您好,Dietrich,感谢您的反馈。看来我对这件事不清楚。我正在尝试为 df1 上的所有行应用一个函数并将值附加到 subdf。如果 df1[''start']==df1['end'] 的值,我想相应地附加到 subdf。如果不是,我想根据 else 语句附加 subdf
  • 正如我所说,df['start'] == df['end'] 是模棱两可的。你是什​​么意思?你的意思是所有行吗?有行吗?你想每行做一些不同的事情吗?
【解决方案2】:

正如 Dietrich 指出的,s_datee_date 以及在函数顶部声明的所有其他变量都是 Series 的。它们是您数据框中的整列。但我怀疑那不是你的什么。您正在尝试为每一行运行time_add。但你没有这样做,因为你打电话给time_add(df1)。它将在整个数据帧上执行,索引它将返回一整列。

改变

time_add(df1)

df = df1.apply(time_add, axis=1)

【讨论】:

    猜你喜欢
    • 2021-11-20
    相关资源
    最近更新 更多