numpy dataframe 获取单列中的最大差异

huangapple go评论64阅读模式
英文:

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 是最快的方法。其他方法较慢:

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:

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

huangapple
  • 本文由 发表于 2023年7月13日 00:25:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672676.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定