如何计算 MultiIndex DataFrame 中每天的行数?
How to count number of rows per day in a MultiIndex'ed DataFrame?
我有一个带有两级 MultiIndex 的 DataFrame。第一级 date
是 DatetimeIndex,第二级 name
只是一些字符串。数据间隔为 10 分钟。
如何在此 MultiIndex 的第一级按日期分组并计算每天的行数?
我怀疑 DatetimeIndex 耦合到 MultiIndex 给我带来了问题,因为
data.groupby(pd.TimeGrouper(freq='D')).count()
给我
TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'MultiIndex'
我也试过写
data.groupby(data.index.levels[0].date).count()
这导致
ValueError: Grouper and axis must be same length
例如,我怎样才能使石斑鱼变长(即包括重复的索引值,现在省略它会使它比轴短)?
谢谢!
您可以在 Grouper
中使用 level
关键字。 (另请注意 TimeGrouper
已弃用)。这个参数是
the level for the target index.
示例数据帧:
dates = pd.date_range('2017-01', freq='10MIN', periods=1000)
strs = ['aa'] * 1000
df = pd.DataFrame(np.random.rand(1000,2), index=pd.MultiIndex.from_arrays((dates, strs)))
解决方案:
print(df.groupby(pd.Grouper(freq='D', level=0)).count())
0 1
2017-01-01 144 144
2017-01-02 144 144
2017-01-03 144 144
2017-01-04 144 144
2017-01-05 144 144
2017-01-06 144 144
2017-01-07 136 136
更新:您在评论中指出,您希望删除结果计数中的零。例如,假设您的 DataFrame 实际上丢失了几天:
df = df.drop(df.index[140:400])
print(df.groupby(pd.Grouper(freq='D', level=0)).count())
0 1
2017-01-01 140 140
2017-01-02 0 0
2017-01-03 32 32
2017-01-04 144 144
2017-01-05 144 144
2017-01-06 144 144
2017-01-07 136 136
据我所知,无法排除 .count
中的零计数。相反,您可以使用上面的结果来删除零。
第一个解决方案(可能不太可取,因为它在引入 np.nan
时将 int
结果转换为 float
,将是
res = df.groupby(pd.Grouper(freq='D', level=0)).count()
res = res.replace(0, np.nan).dropna()
第二个更好的解决方案,在我看来,来自 here:
res = res[(res.T != 0).any()]
print(res) # notice - excludes 2017-01-02
0 1
2017-01-01 140 140
2017-01-03 32 32
2017-01-04 144 144
2017-01-05 144 144
2017-01-06 144 144
2017-01-07 136 136
.any
来自 NumPy,移植到 pandas,并且 returns 当任何元素在请求的轴上为真时为真。
假设 Dataframe 看起来像这样
d=pd.DataFrame([['Mon','foo',3],['Tue','bar',6],['Wed','qux',9]],
columns=['date','name','amount'])\
.set_index(['date','name'])
您可以仅针对此分组操作从索引中删除名称
d.reset_index('name', drop=True)\
.groupby('date')\
['amount'].count()
我有一个带有两级 MultiIndex 的 DataFrame。第一级 date
是 DatetimeIndex,第二级 name
只是一些字符串。数据间隔为 10 分钟。
如何在此 MultiIndex 的第一级按日期分组并计算每天的行数?
我怀疑 DatetimeIndex 耦合到 MultiIndex 给我带来了问题,因为
data.groupby(pd.TimeGrouper(freq='D')).count()
给我
TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'MultiIndex'
我也试过写
data.groupby(data.index.levels[0].date).count()
这导致
ValueError: Grouper and axis must be same length
例如,我怎样才能使石斑鱼变长(即包括重复的索引值,现在省略它会使它比轴短)?
谢谢!
您可以在 Grouper
中使用 level
关键字。 (另请注意 TimeGrouper
已弃用)。这个参数是
the level for the target index.
示例数据帧:
dates = pd.date_range('2017-01', freq='10MIN', periods=1000)
strs = ['aa'] * 1000
df = pd.DataFrame(np.random.rand(1000,2), index=pd.MultiIndex.from_arrays((dates, strs)))
解决方案:
print(df.groupby(pd.Grouper(freq='D', level=0)).count())
0 1
2017-01-01 144 144
2017-01-02 144 144
2017-01-03 144 144
2017-01-04 144 144
2017-01-05 144 144
2017-01-06 144 144
2017-01-07 136 136
更新:您在评论中指出,您希望删除结果计数中的零。例如,假设您的 DataFrame 实际上丢失了几天:
df = df.drop(df.index[140:400])
print(df.groupby(pd.Grouper(freq='D', level=0)).count())
0 1
2017-01-01 140 140
2017-01-02 0 0
2017-01-03 32 32
2017-01-04 144 144
2017-01-05 144 144
2017-01-06 144 144
2017-01-07 136 136
据我所知,无法排除 .count
中的零计数。相反,您可以使用上面的结果来删除零。
第一个解决方案(可能不太可取,因为它在引入 np.nan
时将 int
结果转换为 float
,将是
res = df.groupby(pd.Grouper(freq='D', level=0)).count()
res = res.replace(0, np.nan).dropna()
第二个更好的解决方案,在我看来,来自 here:
res = res[(res.T != 0).any()]
print(res) # notice - excludes 2017-01-02
0 1
2017-01-01 140 140
2017-01-03 32 32
2017-01-04 144 144
2017-01-05 144 144
2017-01-06 144 144
2017-01-07 136 136
.any
来自 NumPy,移植到 pandas,并且 returns 当任何元素在请求的轴上为真时为真。
假设 Dataframe 看起来像这样
d=pd.DataFrame([['Mon','foo',3],['Tue','bar',6],['Wed','qux',9]],
columns=['date','name','amount'])\
.set_index(['date','name'])
您可以仅针对此分组操作从索引中删除名称
d.reset_index('name', drop=True)\
.groupby('date')\
['amount'].count()