我正在使用 Pandas v1.1.0 通过滚动计数、求和和均值运行 group,我注意到滚动计数比滚动均值和总和慢得多。这似乎违反直觉,因为我们可以从平均值和总和中得出计数并节省时间。这是一个错误还是我错过了什么?多谢指教。
import pandas as pd
# Generate sample df
df = pd.DataFrame({'column1': range(600), 'group': 5*['l'+str(i) for i in range(120)]})
# sort by group for easy/efficient joining of new columns to df
df=df.sort_values('group',kind='mergesort').reset_index(drop=True)
# timing of groupby rolling count, sum and mean
%timeit df['mean']=df.groupby('group').rolling(3,min_periods=1)['column1'].mean().values
%timeit df['sum']=df.groupby('group').rolling(3,min_periods=1)['column1'].sum().values
%timeit df['count']=df.groupby('group').rolling(3,min_periods=1)['column1'].count().values
### Output
6.14 ms ± 812 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
5.61 ms ± 179 µs per loop (mean ± std. …Run Code Online (Sandbox Code Playgroud) 我在数据和每个组内都有值分组,我想检查组内的值是否低于此值8.如果满足此条件,则从数据集中删除整个组.
请注意我所指的值位于分组列的另一列.
示例输入:
Groups Count
1 7
1 11
1 9
2 12
2 15
2 21
Run Code Online (Sandbox Code Playgroud)
输出:
Groups Count
2 12
2 15
2 21
Run Code Online (Sandbox Code Playgroud) Pandas 查找功能将在未来版本中弃用。正如警告所建议的,建议使用 .melt 和 .loc 作为替代。
df = pd.DataFrame({'B': ['X', 'X' , 'Y', 'X', 'Y', 'Y', 'X', 'X', 'Y', 'Y', 'X', 'Y'],
'group': ["IT", "IT", "IT", "MV", "MV", "MV", "IT", "MV", "MV", "IT", "IT", "MV"]})
a = pd.concat([df, df['B'].str.get_dummies()], axis=1).groupby('group').rolling(3,
min_periods=1).sum().sort_index(level=1).reset_index(drop=True)
df['count'] = a.lookup(df.index, df['B'])
# Output Warning:
# <ipython-input-16-e5b517460c82>:7: FutureWarning: The 'lookup' method is deprecated and will be
# removed in a future version. You can use DataFrame.melt and DataFrame.loc as a substitute.
Run Code Online (Sandbox Code Playgroud)
但是,替代方案似乎不太优雅且速度较慢:
b = pd.melt(a, value_vars=a.columns, var_name='B', …Run Code Online (Sandbox Code Playgroud) 我试图按组获取多个列的滚动总和,在日期时间列上滚动(即在指定的时间间隔内)。滚动一列似乎工作正常,但是当我通过矢量化滚动多列时,我得到了意想不到的结果。
我的第一次尝试:
df = pd.DataFrame({"column1": range(6),
"column2": range(6),
'group': 3*['A','B'],
'date':pd.date_range("20190101", periods=6)})
(df.groupby('group').rolling("1d", on='date')['column1'].sum()).groupby('group').shift(fill_value=0)
# output:
group date
A 2019-01-01 0.0
2019-01-03 0.0
2019-01-05 2.0
B 2019-01-02 0.0
2019-01-04 1.0
2019-01-06 3.0
Name: column1, dtype: float64
Run Code Online (Sandbox Code Playgroud)
上面产生了预期的结果,但是我在此过程中丢失了原始索引。由于在我的数据中,某些日期是相同的,因此我必须在组+日期上连接回原始数据框,这是低效的。因此,我应用了以下方法来避免这种情况并保留原始索引:
df.groupby('group').apply(lambda x: x.rolling("1d", on='date')['column1'].sum().shift(fill_value=0))
# output:
group
A 0 0.0
2 0.0
4 2.0
B 1 0.0
3 1.0
5 3.0
Name: column1, dtype: float64
Run Code Online (Sandbox Code Playgroud)
这样,我可以通过对索引进行排序,轻松地将其分配给原始 df 的新列。现在我想对“column2”重复相同的操作,并通过矢量化来完成此操作。然而,得到的结果却出乎我的意料:
df.groupby('group').apply(lambda x: x.rolling("1d", on='date')[['column1','column2']].sum().shift(fill_value=0))
# output:
column1 column2 date
0 0.0 0.0 1970-01-01
1 0.0 …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个新列,其中包含以另一列的值为条件的组平均值。通过示例可以最好地解释这一点:
df = pd.DataFrame({'A': [59000000, 65000000, 434000, 434000, 434000, 337000, 11300, 11300, 11300],
'B': [1, 1 , 0, 1, 0, 0, 1, 1, 0],
'group': ["IT", "IT", "IT", "MV", "MV", "MV", "IT", "MV", "MV"]})
df
A B group
0 59000000 1 IT
1 65000000 1 IT
2 434000 0 IT
3 434000 1 MV
4 434000 0 MV
5 337000 0 MV
6 11300 1 IT
7 11300 1 MV
8 11300 0 MV
Run Code Online (Sandbox Code Playgroud)
我已经设法解决了这个问题,但我正在寻找代码行数更少并且可能更高效的东西。
x = df.loc[df['B']==1].groupby('group', as_index=False)['A'].mean()
x.rename(columns …Run Code Online (Sandbox Code Playgroud) 我想按组创建一个新列,其中包含另一列中最大值的相应值。这最好通过示例来解释:
data = {'group':['g1', 'g1', 'g1', 'g1', 'g1', 'g1', 'g2', 'g2', 'g2', 'g2', 'g2'],
'A':[3, 1, 8, 2, 6, -1, 0, 13, -4, 0, 1],
'B':[5, 2, 3, 7, 11, -1, 4,-1, 1, 0, 2]}
df = pd.DataFrame(data)
df
Run Code Online (Sandbox Code Playgroud)
以下解决方案可用作快捷方式,但我觉得有更好的方法来做到这一点:
df.loc[:, 'Amax'] = df.loc[df.groupby('group')['B'].idxmax(), 'A']
df.loc[:, 'Amax'] = df.groupby('group')['Amax'].transform('median')
group A B Amax
0 g1 3 5 6.0
1 g1 1 2 6.0
2 g1 8 3 6.0
3 g1 2 7 6.0
4 g1 6 11 6.0
5 g1 …Run Code Online (Sandbox Code Playgroud) 试图理解为什么x ++在打印后计算,而x = x + 1在打印之前计算:
int x = 3;
System.out.println("Ans: " + (x++));
System.out.println("Ans: " + (x=x+1));
Ans: 3
Ans: 5
Run Code Online (Sandbox Code Playgroud)