Pandas Dataframe 中本月与前几个月的不同计算
Different calculations for this month compared to previous months in Pandas Dataframe
考虑示例数据:
Month Members
JUL 10
AUG 10
SEP 10
我想添加一个新列,即 MemberValue,但如果月份不是当前月份(当前为 2021 年 9 月),我希望该列将成员值乘以 10,如果月份值是当前月份,则乘以 100月。预期的输出将是这样的:
Month Members MemberValue
JUL 10 100
AUG 10 100
SEP 10 1000
我已经尝试了各种版本的条件语句,并继续我们之前在各种上下文中看到的“真值不明确”。我可以计算月份的三个字母缩写和月份的数值(即 SEP 或 9),但使用它们作为计算 MemberValue 列的比较会产生错误。我确信我遗漏了一些简单的东西,但无法破解这个。感谢您的观看。
我最近一次失败的尝试:
if df.index != months-1:
df['MemberValue'] = df['Members'] * 10
else:
df['MemberValue'] = df['Members'] * 100
之前的另一次尝试:
cur_month_name = str(today_date_time.strftime('%b')).upper()
if df['Month'] != cur_month_name:
df['MemberValue'] = df['Members'] * 10
else:
df['MemberValue'] = df['Members'] * 100
也失败了。
您可以使用 strftime
获取缩写月份名称,并使用 np.where
应用您的操作:
cur_month_name = pd.Timestamp.today().strftime('%b').upper()
df['MemberValue'] = np.where(df['Month'] == cur_month_name,
df['Members']*100, df['Members']*10)
输出:
>>> df
Month Members MemberValue
0 JUL 10 100
1 AUG 10 100
2 SEP 10 1000
>>> cur_month_name
'SEP'
对于您之前的尝试,您的想法是使用月份名称是好的,但您要求 Python 对值列表(真/假)进行测试。为此,您需要在每一行而不是整个系列上应用测试:
>>> df.apply(lambda x: x['Members']*100 if x['Month'] == cur_month_name
else x['Members']*10, axis=1)
0 100
1 100
2 1000
dtype: int64
curr_month_short = str.upper(pd.Timestamp.now().month_name())[0:3]
df.loc[df['Month'] != curr_month_short, 'MemberValue'] = df['Members'] * 10
df.loc[df['Month'] == curr_month_short, 'MemberValue'] = df['Members'] * 100
输出:
Out[13]:
Month Members MemberValue
0 JUL 10 100.0
1 AUG 10 100.0
2 SEP 10 1000.0
第一行获取月份的简称 - 只需获取今天的月份名称,然后将前 3 个字母切片(并应用 str.upper
)即可。
df.loc[df['Month'] != curr_month_short, 'MemberValue']
select df['Month']
不同于 curr_month_short
的所有行,并将 MemberValue
的值分配给列 MemberValue
].当前月份相同的所有行都相同 curr_month_short
至于你的代码:注意行 df['Month'] != cur_month_name
returns a series with boolean values - true or false for each row。 if
语句不知道如何处理它,因此出现错误。 if... else
如果您一次将逻辑应用于一行(比方说,遍历所有行),则逻辑可以很好地工作。
在我的示例中,在 .loc
上使用此条件是您想要它做的:仅获取语句为“真”的行,并将值应用于它们。
您的代码应如下所示:
cur_month_name = str(today_date_time.strftime('%b')).upper()
boolean_series = df['Month'] != cur_month_name
df.loc[boolean_series, 'MemberValue'] = df['Members'] * 10
df.loc[~boolean_series, 'MemberValue'] = df['Members'] * 100
('~'运算符 returns 相反:true 变成 false,false 变成 true)
考虑示例数据:
Month Members
JUL 10
AUG 10
SEP 10
我想添加一个新列,即 MemberValue,但如果月份不是当前月份(当前为 2021 年 9 月),我希望该列将成员值乘以 10,如果月份值是当前月份,则乘以 100月。预期的输出将是这样的:
Month Members MemberValue
JUL 10 100
AUG 10 100
SEP 10 1000
我已经尝试了各种版本的条件语句,并继续我们之前在各种上下文中看到的“真值不明确”。我可以计算月份的三个字母缩写和月份的数值(即 SEP 或 9),但使用它们作为计算 MemberValue 列的比较会产生错误。我确信我遗漏了一些简单的东西,但无法破解这个。感谢您的观看。
我最近一次失败的尝试:
if df.index != months-1:
df['MemberValue'] = df['Members'] * 10
else:
df['MemberValue'] = df['Members'] * 100
之前的另一次尝试:
cur_month_name = str(today_date_time.strftime('%b')).upper()
if df['Month'] != cur_month_name:
df['MemberValue'] = df['Members'] * 10
else:
df['MemberValue'] = df['Members'] * 100
也失败了。
您可以使用 strftime
获取缩写月份名称,并使用 np.where
应用您的操作:
cur_month_name = pd.Timestamp.today().strftime('%b').upper()
df['MemberValue'] = np.where(df['Month'] == cur_month_name,
df['Members']*100, df['Members']*10)
输出:
>>> df
Month Members MemberValue
0 JUL 10 100
1 AUG 10 100
2 SEP 10 1000
>>> cur_month_name
'SEP'
对于您之前的尝试,您的想法是使用月份名称是好的,但您要求 Python 对值列表(真/假)进行测试。为此,您需要在每一行而不是整个系列上应用测试:
>>> df.apply(lambda x: x['Members']*100 if x['Month'] == cur_month_name
else x['Members']*10, axis=1)
0 100
1 100
2 1000
dtype: int64
curr_month_short = str.upper(pd.Timestamp.now().month_name())[0:3]
df.loc[df['Month'] != curr_month_short, 'MemberValue'] = df['Members'] * 10
df.loc[df['Month'] == curr_month_short, 'MemberValue'] = df['Members'] * 100
输出:
Out[13]:
Month Members MemberValue
0 JUL 10 100.0
1 AUG 10 100.0
2 SEP 10 1000.0
第一行获取月份的简称 - 只需获取今天的月份名称,然后将前 3 个字母切片(并应用 str.upper
)即可。
df.loc[df['Month'] != curr_month_short, 'MemberValue']
select df['Month']
不同于 curr_month_short
的所有行,并将 MemberValue
的值分配给列 MemberValue
].当前月份相同的所有行都相同 curr_month_short
至于你的代码:注意行 df['Month'] != cur_month_name
returns a series with boolean values - true or false for each row。 if
语句不知道如何处理它,因此出现错误。 if... else
如果您一次将逻辑应用于一行(比方说,遍历所有行),则逻辑可以很好地工作。
在我的示例中,在 .loc
上使用此条件是您想要它做的:仅获取语句为“真”的行,并将值应用于它们。
您的代码应如下所示:
cur_month_name = str(today_date_time.strftime('%b')).upper()
boolean_series = df['Month'] != cur_month_name
df.loc[boolean_series, 'MemberValue'] = df['Members'] * 10
df.loc[~boolean_series, 'MemberValue'] = df['Members'] * 100
('~'运算符 returns 相反:true 变成 false,false 变成 true)