英文:
numpy dataframe get maximum difference in a single column
问题
我想在一个国家数据框中获取温度变化最大的部分。
我的第一个想法是进行分组:df.groupby('country_code')['temperature'].max()
,df.groupby('country_code')['temperature'].min()
,然后相减,并获取最大值。
我猜想可能有更好的方法吗?
英文:
I want to get the biggest temperature change in a dataframe of countries.
My first idea was to make groups: df.groupby('country_code')['temperature'].max()
, df.groupby('country_code')['temperature'].min()
, subtract them, and get the maximum.
I guess there is a better way to to that?
答案1
得分: 2
看起来将自定义的 max-min
函数传递给 DataFrameGroupBy.agg
是最快的方法。其他方法较慢:
- 在
agg
内使用np.ptp
; - 使用
apply
(参见 @MariaKozlova 的解决方案)
import pandas as pd
import numpy as np
np.random.seed(0) # 用于可重复性
# 示例数据框:10个国家,每个国家有5个温度值
data = {'country_code': np.repeat(range(10),5), 'temperature': np.random.randint(-10,50,50)}
df = pd.DataFrame(data)
# 方法1(将 lambda 函数传递给 `agg`)
out = df.groupby('country_code', sort=False)['temperature'].agg(lambda x: max(x) - min(x))
# 方法2(将 `np.ptp` 传递给 `agg`)
out2 = df.groupby('country_code', sort=False).agg({'temperature': np.ptp})
out.equals(out2['temperature'])
# True
out
country_code
0 53
1 56
2 44
3 57
4 23
5 29
6 42
7 47
8 27
9 25
Name: temperature, dtype: int64
性能比较
# 有趣的是,`np.ptp` 实际上要慢得多
%timeit df.groupby('country_code', sort=False)['temperature'].agg(lambda x: max(x) - min(x))
# 238 微秒 ± 4.35 微秒每次循环(均值 ± 7 次运行的标准偏差,每次循环 1000 次)
%timeit df.groupby('country_code', sort=False).agg({'temperature': np.ptp})
# 1.26 毫秒 ± 22 微秒每次循环(均值 ± 7 次运行的标准偏差,每次循环 1000 次)
# 添加 `apply` 的比较(由 @MariaKolzova 提供的解决方案)
def temp_range(group):
return group.max() - group.min()
%timeit df.groupby('country_code')['temperature'].apply(temp_range)
# 434 微秒 ± 9.26 微秒每次循环(均值 ± 7 次运行的标准偏差,每次循环 1000 次)
英文:
Looks like passing a custom max-min
function to DataFrameGroupBy.agg
is fastest. The alternatives are slower:
- using
np.ptp
insideagg
; - using
apply
(see solution by @MariaKozlova)
import pandas as pd
import numpy as np
np.random.seed(0) # for reproducibility
# sample df: 10 countries with 5 temperatures
data = {'country_code': np.repeat(range(10),5), 'temperature': np.random.randint(-10,50,50)}
df = pd.DataFrame(data)
# method1 (pass lambda function to `agg`)
out = df.groupby('country_code', sort=False)['temperature'].agg(lambda x: max(x) - min(x))
# method2 (pass `np.ptp` to `agg`)
out2 = df.groupby('country_code', sort=False).agg({'temperature': np.ptp})
out.equals(out2['temperature'])
# True
out
country_code
0 53
1 56
2 44
3 57
4 23
5 29
6 42
7 47
8 27
9 25
Name: temperature, dtype: int64
Performance comparison
# intriguingly, `np.ptp` is actually quite a bit slower
%timeit df.groupby('country_code', sort=False)['temperature'].agg(lambda x: max(x) - min(x))
# 238 µs ± 4.35 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df.groupby('country_code', sort=False).agg({'temperature': np.ptp})
# 1.26 ms ± 22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# adding comparison for `apply` (solution by @MariaKolzova)
def temp_range(group):
return group.max() - group.min()
%timeit df.groupby('country_code')['temperature'].apply(temp_range)
# 434 µs ± 9.26 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
答案2
得分: 1
这里有一个稍微不同的方法,只涉及一个组集合:
def temp_range(group):
return group.max() - group.min()
df.groupby('country_code')['temperature'].apply(temp_range)
不确定这是否更好。
英文:
Here's a slightly different approach, dealing with only one set of groups
def temp_range(group):
return group.max() - group.min()
df.groupby('country_code')['temperature'].apply(temp_range)
Not sure if it's better though
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论