Pandas 具有动态列的 groupby countif
Pandas groupby countif with dynamic columns
我有一个具有这种结构的数据框:
time,10.0.0.103,10.0.0.24
2016-10-12 13:40:00,157,172
2016-10-12 14:00:00,0,203
2016-10-12 14:20:00,0,0
2016-10-12 14:40:00,0,200
2016-10-12 15:00:00,185,208
它详细说明了给定 20 分钟内每个 IP 地址的事件数。我需要一个数据框,说明每个矿工有多少 20 分钟的时间段有 0 个事件,我需要从中导出 IP 'uptime' 的百分比。 IP 地址的数量是动态的。期望的输出:
IP,noEvents,uptime
10.0.0.103,3,40
10.0.0.24,1,80
我试过 groupby、agg 和 lambda 都没有用。通过动态列执行 'countif' 的最佳方法是什么?
您可以同时使用 sum
and mean
of boolean mask by condition df == 0
. Last concat
Series
:
df.set_index('time', inplace=True)
mask = (df == 0)
print (mask)
10.0.0.103 10.0.0.24
time
2016-10-12 13:40:00 False False
2016-10-12 14:00:00 True False
2016-10-12 14:20:00 True True
2016-10-12 14:40:00 True False
2016-10-12 15:00:00 False False
noEvents = mask.sum()
print (noEvents)
10.0.0.103 3
10.0.0.24 1
dtype: int64
uptime = 100 * mask.mean()
print (uptime)
10.0.0.103 60.0
10.0.0.24 20.0
dtype: float64
print (pd.concat([noEvents, uptime], axis=1, keys=('noEvents','uptime'))
.reset_index()
.rename(columns={'index':'IP'}))
IP noEvents uptime
0 10.0.0.103 3 60.0
1 10.0.0.24 1 20.0
转置 DF
:
df = df.T
由于您尝试使用 groupby
,您可以进一步使用 value_counts
在堆叠它以生成 series
对象后获取每个组中的零数然后将其拆回 DF
,如图所示:
grp = df.stack().to_frame('val').groupby(level=0)['val']
df['noEvents'] = grp.value_counts().unstack()[0]
稍后,将值除以该组的大小以获得它的百分比分布:
df['upTime'] = (100*df['noEvents']/grp.size())
出于审美目的:
df = df[['noEvents', 'upTime']].astype(int)
df.index.name = 'IP'
df.columns.name = None
df
我有一个具有这种结构的数据框:
time,10.0.0.103,10.0.0.24
2016-10-12 13:40:00,157,172
2016-10-12 14:00:00,0,203
2016-10-12 14:20:00,0,0
2016-10-12 14:40:00,0,200
2016-10-12 15:00:00,185,208
它详细说明了给定 20 分钟内每个 IP 地址的事件数。我需要一个数据框,说明每个矿工有多少 20 分钟的时间段有 0 个事件,我需要从中导出 IP 'uptime' 的百分比。 IP 地址的数量是动态的。期望的输出:
IP,noEvents,uptime
10.0.0.103,3,40
10.0.0.24,1,80
我试过 groupby、agg 和 lambda 都没有用。通过动态列执行 'countif' 的最佳方法是什么?
您可以同时使用 sum
and mean
of boolean mask by condition df == 0
. Last concat
Series
:
df.set_index('time', inplace=True)
mask = (df == 0)
print (mask)
10.0.0.103 10.0.0.24
time
2016-10-12 13:40:00 False False
2016-10-12 14:00:00 True False
2016-10-12 14:20:00 True True
2016-10-12 14:40:00 True False
2016-10-12 15:00:00 False False
noEvents = mask.sum()
print (noEvents)
10.0.0.103 3
10.0.0.24 1
dtype: int64
uptime = 100 * mask.mean()
print (uptime)
10.0.0.103 60.0
10.0.0.24 20.0
dtype: float64
print (pd.concat([noEvents, uptime], axis=1, keys=('noEvents','uptime'))
.reset_index()
.rename(columns={'index':'IP'}))
IP noEvents uptime
0 10.0.0.103 3 60.0
1 10.0.0.24 1 20.0
转置 DF
:
df = df.T
由于您尝试使用 groupby
,您可以进一步使用 value_counts
在堆叠它以生成 series
对象后获取每个组中的零数然后将其拆回 DF
,如图所示:
grp = df.stack().to_frame('val').groupby(level=0)['val']
df['noEvents'] = grp.value_counts().unstack()[0]
稍后,将值除以该组的大小以获得它的百分比分布:
df['upTime'] = (100*df['noEvents']/grp.size())
出于审美目的:
df = df[['noEvents', 'upTime']].astype(int)
df.index.name = 'IP'
df.columns.name = None
df