GVKun编程网logo

通过pandas数据框按pandas ID中的两个日期之间的行数进行计数(pandas根据时间筛选)

10

在这篇文章中,我们将为您详细介绍通过pandas数据框按pandasID中的两个日期之间的行数进行计数的内容,并且讨论关于pandas根据时间筛选的相关问题。此外,我们还会涉及一些关于40期《Pand

在这篇文章中,我们将为您详细介绍通过pandas数据框按pandas ID中的两个日期之间的行数进行计数的内容,并且讨论关于pandas根据时间筛选的相关问题。此外,我们还会涉及一些关于40期《Pandas数据处理与分析》|pandas基础笔记2|pandas 基础|joyfulPandas、pandas应用函数返回多个值到pandas数据帧中的行、Pandas数据分析-pandas数据框的多层索引、Pandas数据框按日期时间月份分组的知识,以帮助您更全面地了解这个主题。

本文目录一览:

通过pandas数据框按pandas ID中的两个日期之间的行数进行计数(pandas根据时间筛选)

通过pandas数据框按pandas ID中的两个日期之间的行数进行计数(pandas根据时间筛选)

我有以下测试DataFrame:

import randomfrom datetime import timedeltaimport pandas as pdimport datetime#create test range of datesrng=pd.date_range(datetime.date(2015,1,1),datetime.date(2015,7,31))rnglist=rng.tolist()testpts = range(100,121)#create test dataframed={''jid'':[i for i in range(100,121)], ''cid'':[random.randint(1,2) for _ in testpts],    ''stdt'':[rnglist[random.randint(0,len(rng))] for _ in testpts]}df=pd.DataFrame(d)df[''enddt''] = df[''stdt'']+timedelta(days=random.randint(2,32))

它给出了如下所示的数据框,其中包含公司ID列“ cid”,唯一ID列“ jid”,开始日期“ stdt”和enddt“ enddt”。

   cid  jid       stdt      enddt0    1  100 2015-07-06 2015-07-131    1  101 2015-07-15 2015-07-222    2  102 2015-07-12 2015-07-193    2  103 2015-07-07 2015-07-144    2  104 2015-07-14 2015-07-215    1  105 2015-07-11 2015-07-186    1  106 2015-07-12 2015-07-197    2  107 2015-07-01 2015-07-088    2  108 2015-07-10 2015-07-179    2  109 2015-07-09 2015-07-16

我需要做的是:
计算min(stdt)和max(enddt)之间每个date(newdate)的cid发生的jid数目,其中newdate在stdt和enddt之间。

结果数据集应为每个cid具有一个数据帧,该数据帧的日期范围(新日期)在每个cid的min(stdt)和max(enddt)之间,并且该数字的计数(cnt)
jid表示newdate在min(stdt)和max(enddt)之间。得到的DataFrame应该看起来像(这仅是使用上述数据的1 cid):

cid newdate cnt1   2015-07-06  11   2015-07-07  11   2015-07-08  11   2015-07-09  11   2015-07-10  11   2015-07-11  21   2015-07-12  31   2015-07-13  31   2015-07-14  21   2015-07-15  31   2015-07-16  31   2015-07-17  31   2015-07-18  31   2015-07-19  21   2015-07-20  11   2015-07-21  11   2015-07-22  1

我相信应该有一种方法可以使用pandas groupby(groupby cid)和某种形式的lambda(?)以Python方式创建此新数据框。

我目前正在运行一个循环,为每个cid(将cid行从主df中切出),在循环中确定相关的日期范围(每个cid帧的最小stdt和max
enddt,然后确定每个新日期(范围为minate) -maxdate),它计算jid的数目,其中newdate在每个jid的stdt和enddt之间。

但是,从资源和时间的角度来看,这是非常昂贵的。数以千计的jid花费了整整一天的时间。我希望这里有一个简单的熊猫解决方案。

答案1

小编典典

对于这些问题,我通常的处理方法是围绕更改累加器的事件进行思考。我们看到的每个新的“ stdt”都会使计数增加+1;我们看到的每个“
enddt”都加-1。(第二天加-1,至少如果我解释您的方式“在两者之间”。某些时候,我认为我们应该禁止过于含糊地使用该词。)

IOW,如果我们将您的框架变成类似

>>> df.head()    cid  jid  change       date0     1  100       1 2015-01-061     1  101       1 2015-01-0721    1  100      -1 2015-01-1622    1  101      -1 2015-01-1717    1  117       1 2015-03-01

那么我们想要的只是change(经过适当的重组后)的累积总和。例如,类似

df["enddt"] += timedelta(days=1)df = pd.melt(df, id_vars=["cid", "jid"], var_name="change", value_name="date")df["change"] = df["change"].replace({"stdt": 1, "enddt": -1})df = df.sort(["cid", "date"])df = df.groupby(["cid", "date"],as_index=False)["change"].sum()df["count"] = df.groupby("cid")["change"].cumsum()new_time = pd.date_range(df.date.min(), df.date.max())df_parts = []for cid, group in df.groupby("cid"):    full_count = group[["date", "count"]].set_index("date")    full_count = full_count.reindex(new_time)    full_count = full_count.ffill().fillna(0)    full_count["cid"] = cid    df_parts.append(full_count)df_new = pd.concat(df_parts)

这给了我类似的东西

>>> df_new.head(15)            count  cid2015-01-03      0    12015-01-04      0    12015-01-05      0    12015-01-06      1    12015-01-07      2    12015-01-08      2    12015-01-09      2    12015-01-10      2    12015-01-11      2    12015-01-12      2    12015-01-13      2    12015-01-14      2    12015-01-15      2    12015-01-16      1    12015-01-17      0    1

关于您的期望可能存在一对一的差异;您可能对如何jid在同一时间窗口中处理多个重叠的s有不同的想法(此处将它们计为2);但是即使必须微调细节,处理事件的基本思想也应被证明是有用的。

40期《Pandas数据处理与分析》|pandas基础笔记2|pandas 基础|joyfulPandas

40期《Pandas数据处理与分析》|pandas基础笔记2|pandas 基础|joyfulPandas

目录

  • 一、文件的读取和写入
  • 基本数据结构
      • 1. Series
      • 2. DataFrame
          • 方法一(data,index,columns)
          • 方法二(data(columns),index)
  • 常用基本函数
    • 1. 汇总函数
    • 2. 特征统计函数
    • 3.唯一值函数
      • 4. 替换函数
        • 数值替换 round,abs,clip
            • 练习
      • 5.排序函数
      • 6.apply 方法
    • 四、窗口对象
      • 1. 滑窗对象
            • 练习2
      • 2. 扩张窗口
    • 五、练习
      • Ex2:指数加权窗口

import numpy as np
import pandas as pd

查看pandas 版本pd.__version__

一、文件的读取和写入

  1. 文件的读取
    pd.read_csv()#csv
    pd.read_table()#txt
    pd.read_excel()#excel

常用的公共参数
header=None# 第一行不作为列名
index_col#表示把某一列或几列作为索引
usecols#读取列的集合
parse_dates#表示需要转化为时间的列

在这里插入图片描述

nrows#读取的数据的行数

Attention:
读取txt文件的时候,经常遇到分隔符非空格的情况,read_table有个分割参数 sep,用户可以自定义分割符号,进行txt数据的读取.
sep是正则参数,|需要转义成|

在这里插入图片描述

pd.read_table('../data/my_table_special_sep.txt', sep=' \|\|\|\| ', engine='python')
  1. 数据的写入
df.to_csv('...',index=False)
#当索引没有任何意义的时候可以在保存的时候去除
***** to_csv可以保存txt文件,可以自定义分隔符sep参数,一般设置成制表符'\t'

如果要将表格转换成markdown和latex可以使用to_markdown和to_latex,需要安装tabulate包。

基本数据结构

1. Series

Series一般由四个部分组成,分别是序列的值data、索引index(name)、存储类型dtype、序列的名字name
其中,索引也可以指定它的名字,默认为空。

s=pd.Series(data=[100,'a',{'dic1':5}],
index=pd.Index(['id1':20,'third'],name='my_idx'),
dtype='object',
name='my_name')

在这里插入图片描述

#获取属性
s.values
s.index //s.index.name#获取索引的名字
s[index_item]#取出单个索引的值 如s['third']
s.dtype
s.name
s.shape

2. DataFrame

DataFrame在Series的基础上增加了列索引


方法一(data,index,columns)
data=[[1,'a',1.2],[2,'b',2.2],[3,'c',3.2]]
df=pd.DataFrame(data=data, 
index=['row_%d'%i for i in range(3)], ⭐
columns=['col_0','col_1','col_2'])
方法二(data(columns),index)

一般而言,更多的时候会采用从列索引名到数据的映射来构造数据框,同时再加上行索引:

df=pd.Dataframe(data={'col_0':[1,2,3]
'col_1':list('abc'),
'col_2':[1.2,2.2,3.2]},
index=['row_%d'%i for i in range(3)])

索引

df['col_0']

在这里插入图片描述

df[['col_0','col_1']]

**加粗样式**

df['col_0']['row_0']

在这里插入图片描述

常用属性

df.values
df.index
df.columns
df.dtypes
df.shape
df.T

常用基本函数

1. 汇总函数

引入数据

df=pd.read_csv('')

在这里插入图片描述

在这里插入图片描述


上述列名依次代表学校、年级、姓名、性别、身高、体重、是否为转系生、体测场次、测试时间、1000米成绩,本章只需使用其中的前七列。
取出数据前7列

df=df[df.columns[:7]]

取出数据前2行

df.head(2)

取出数据后3行

df.tail(3)

info()返回表的信息概况

df.info()

在这里插入图片描述

**describe表中数据数值列对应的主要统计量 **

df.describe()

在这里插入图片描述

更全面的数据汇总 使用pandas-profiling

2. 特征统计函数

sum, mean, median, var, std, max, min

引入df.demo数据

在这里插入图片描述

df_demo=df[['Height','Weight']]
df_demo.mean()
df_demo.max()
df_demo.quantile(0.75)
df_demo.count()
df_demo.idxmax() #获取pandas中series最大值对应的索引。
# idxmin是对应的函数

3.唯一值函数

对序列使用unique,nunique可以分别其唯一值组成的列表和唯一值的个数

df['School'].unique()#唯一值组成的列表
df['School'].nunique()#求某列有多少种不同的数
df['School'].value_counts()#得到唯一值及其对应的频数

观察多个列组合的唯一值 drop_duplicates()
关键参数:
keep:
'first’保留第一次出现的所在行,
‘last’保留最后一行所在行,
False:把所有重复组合所在的行删除

df_demo=df[['Gender','Transfer','Name']]
df_demo.drop_duplicates(['Gender','Transfer'],keep='last')
df['School'].drop_duplicates() # 在Series上也可以使用

duplicated和drop_duplicates的功能类似,但前者返回了是否为唯一值的布尔列表,其keep参数与后者一致。
drop_duplicates等价于把duplicated为True的对应行剔除。

4. 替换函数

替换操作是针对某一个列进行的

pandas中的替换函数可以归纳为三类:映射替换、逻辑替换、数值替换。

映射替换
其中映射替换包含replace方法、第八章中的str.replace方法,第九章中的cat.codes方法
在replace中,可以通过字典构造,或者传入两个列表来进行替换

df['Gender'].replace({'Female':0,'Male':1}).head()
df['Gender'].replace(['Female','Male'],[0,1]).head()

replace特殊方向替换
method参数
ffill:用前面一个最近的未被替换的值进行替换
bfill:使用后面最近的未被替换的值进行替换

在这里插入图片描述

正则替换使用str.replace()
当前版本下对于string类型的正则替换还存在bug,因此如有此需求,请选择str.replace进行替换操作

逻辑替换

s=pd.Series([-1,1.2345,100,-50])
s.where(s<0)
s.where(s<0,100)
s.mask(s<0)#替换满足条件的值为Nan
s.mask(s<10,100)#替换满足条件的值为100

#构造一个bool序列类型,替换满足条件相应的数据
#传入的条件只需是与被调用的Series索引一致的布尔序列
s_condition=pd.Series([True,False,False,True],index=s.index)
s.mask(s_condition,-50)

数值替换 round,abs,clip

它们分别表示按照给定精度round四舍五入、abs取绝对值和clip截断

s=pd.Series([-1,1.2345,100,-50])
s.round(2)
s.clip(0,2)#前两个数分别表示上下截断边界
练习

clip 中,超过边界的只能截断为边界值,如果要把超出边界的替换为自定义的值,应当如何做?

s.clip(0,2).replace({2:100,0:-100})

5.排序函数

其一为值排序(sort_values),其二为索引排序(sort_index)

利用set_index方法把年级和姓名两列作为索引

df_demo = df[['Grade', 'Name', 'Height', 'Weight']].set_index(['Grade','Name'])
df_demo.head(3)
#对身高进行排序,默认参数ascending=True为升序:
df_demo.sort_values('Height').head()

在这里插入图片描述

df_demo.sort_values('Height', ascending=False).head()

在这里插入图片描述


在排序中,经常遇到多列排序的问题,比如在体重相同的情况下,对身高进行排序,并且保持身高降序排列,体重升序排列:

df_demo.sort_values(['Weight','Height'],ascending=[True,False]).head()

索引排序的用法和值排序完全一致,只不过元素的值在索引中,此时需要指定索引层的名字或者层号,用参数level表示。
另外,需要注意的是字符串的排列顺序由字母顺序决定。

df_demo.sort_index(level=['Grade','Name'],ascending=[True,False]).head()

6.apply 方法

apply方法常用于DataFrame的行迭代或者列迭代
apply的参数往往是一个以序列为输入的函数

df_demo = df[['Height', 'Weight']]
def my_mean(x):
     res = x.mean()
     return res
df_demo.apply(my_mean)
=>
df_demo.apply(lambda x:x.mean())
=>
df_demo.apply(lambda x:x.mean(), axis=1).head()

mad函数返回的是一个序列中偏离该序列均值的绝对值大小的均值

df_demo.apply(lambda x:(x-x.mean()).abs().mean())
=>
df_demo.mad()

四、窗口对象

pandas中有3类窗口,分别是滑动窗口rolling、扩张窗口expanding以及指数加权窗口ewm

1. 滑窗对象

要使用滑窗函数,就必须先要对一个序列使用.rolling得到滑窗对象,其最重要的参数为窗口大小window

roller使用的函数

s = pd.Series([1,2,3,4,5])
roller = s.rolling(window = 3)
roller. Mean()

在这里插入图片描述

roller.sum()

在这里插入图片描述


滑动相关系数或滑动协方差

roller.cov(s2)
roller.corr(s2)

在这里插入图片描述

支持使用apply传入自定义函数,其传入值是对应窗口的Series

roller.apply(lambda x:x.mean())

series使用的函数
shift, diff, pct_change是一组类滑窗函数,它们的公共参数为periods=n,默认为1,
分别表示取向前第n个元素的值、与向前第n个元素做差(与Numpy中不同,后者表示n阶差分)、
与向前第n个元素相比计算增长率。这里的n可以为负,表示反方向的类似操作。

s = pd.Series([1,3,6,10,15])
s.shift(2)

它们的功能可以用窗口大小为n+1的rolling方法等价代替:

s.rolling(3).apply(lambda x:list(x)[0]) # s.shift(2)
s.rolling(4).apply(lambda x:list(x)[-1]-list(x)[0]) # s.diff(3)
def my_pct(x):
     L = list(x)
     return L[-1]/L[0]-1
s.rolling(2).apply(my_pct) # s.pct_change()
练习2

rolling对象的默认窗口方向都是向前的,某些情况下用户需要向后的窗口,
例如对1,2,3设定向后窗口为2的sum操作,结果为3,5,NaN,此时应该如何实现向后的滑窗操作?

sd = pd.Series([1, 2, 3])
sd + sd[::-1].shift(1)

2. 扩张窗口

扩张窗口又称累计窗口,可以理解为一个动态长度的窗口,其窗口的大小就是从序列开始处到具体操作的对应位置,其使用的聚合函数会作用于这些逐步扩张的窗口上。具体地说,设序列为a1, a2, a3, a4,则其每个位置对应的窗口即[a1]、[a1, a2]、[a1, a2, a3]、[a1, a2, a3, a4]。

s = pd.Series([1, 3, 6, 10])
s.expanding().mean()

cummax, cumsum, cumprod函数是典型的类扩张窗口函数,请使用expanding对象依次实现它们

s.expanding().sum()  # cummax()
s.expanding().max()  # cumsum() 
s.expanding().apply(lambda x:np.prod(x))# cumprod

五、练习

Ex1:口袋妖怪数据集
现有一份口袋妖怪的数据集,下面进行一些背景说明:

#代表全国图鉴编号,不同行存在相同数字则表示为该妖怪的不同状态

妖怪具有单属性和双属性两种,对于单属性的妖怪,Type 2为缺失值

Total, HP, Attack, Defense, Sp. Atk, Sp. Def, Speed分别代表种族值、体力、物攻、防御、特攻、特防、速度,其中种族值为后6项之和

  1. HP, Attack, Defense, Sp. Atk, Sp. Def, Speed进行加总,验证是否为Total值。

  2. 对于#重复的妖怪只保留第一条记录,解决以下问题:

  • 求第一属性的种类数量和前三多数量对应的种类
  • 求第一属性和第二属性的组合种类
  • 求尚未出现过的属性组合
  1. 按照下述要求,构造Series
  • 取出物攻,超过120的替换为high,不足50的替换为low,否则设为mid
  • 取出第一属性,分别用replaceapply替换所有字母为大写
  • 求每个妖怪六项能力的离差,即所有能力中偏离中位数最大的值,添加到df并从大到小排序

Ex2:指数加权窗口

  1. 作为扩张窗口的ewm窗口

在扩张窗口中,用户可以使用各类函数进行历史的累计指标统计,但这些内置的统计函数往往把窗口中的所有元素赋予了同样的权重。事实上,可以给出不同的权重来赋给窗口中的元素,指数加权窗口就是这样一种特殊的扩张窗口。

其中,最重要的参数是alpha,它决定了默认情况下的窗口权重为 w i = ( 1 − α ) i , i ∈ { 0 , 1 , . . . , t } w_i=(1−\alpha)^i,i\in\{0,1,...,t\} wi=(1α)i,i{0,1,...,t},其中 i = t i=t i=t表示当前元素, i = 0 i=0 i=0表示序列的第一个元素。

从权重公式可以看出,离开当前值越远则权重越小,若记原序列为 x x x,更新后的当前元素为 y t y_t yt,此时通过加权公式归一化后可知:

y t = ∑ i = 0 t w i x t − i ∑ i = 0 t w i = x t + ( 1 − α ) x t − 1 + ( 1 − α ) 2 x t − 2 + . . . + ( 1 − α ) t x 0 1 + ( 1 − α ) + ( 1 − α ) 2 + . . . + ( 1 − α ) t \begin{split}y_t &=\frac{\sum_{i=0}^{t} w_i x_{t-i}}{\sum_{i=0}^{t} w_i} \\&=\frac{x_t + (1 - \alpha)x_{t-1} + (1 - \alpha)^2 x_{t-2} + ...+ (1 - \alpha)^{t} x_{0}}{1 + (1 - \alpha) + (1 - \alpha)^2 + ...+ (1 - \alpha)^{t}}\\\end{split} yt=i=0twii=0twixti=1+(1α)+(1α)2+...+(1α)txt+(1α)xt1+(1α)2xt2+...+(1α)tx0

对于Series而言,可以用ewm对象如下计算指数平滑后的序列:

np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
s.ewm(alpha=0.2).mean().head()

请用expanding窗口实现。

  1. 作为滑动窗口的ewm窗口

从第1问中可以看到,ewm作为一种扩张窗口的特例,只能从序列的第一个元素开始加权。现在希望给定一个限制窗口n,只对包含自身的最近的n个元素作为窗口进行滑动加权平滑。请根据滑窗函数,给出新的wiyt的更新公式,并通过rolling窗口实现这一功能。

教程来源:http://joyfulpandas.datawhale.club/Content/ch2.html

pandas应用函数返回多个值到pandas数据帧中的行

pandas应用函数返回多个值到pandas数据帧中的行

我有一个带有timeindex和3列的数据帧,其中包含3D矢量的坐标:

                         x             y             zts2014-05-15 10:38         0.120117      0.987305      0.1162112014-05-15 10:39         0.117188      0.984375      0.1220702014-05-15 10:40         0.119141      0.987305      0.1191412014-05-15 10:41         0.116211      0.984375      0.1201172014-05-15 10:42         0.119141      0.983398      0.118164

我想对也返回向量的每一行应用转换

def myfunc(a, b, c):    do something    return e, f, g

但是如果我这样做:

df.apply(myfunc, axis=1)

我最后得到了一个以元组为元素的熊猫系列。这是因为apply将在不解压的情况下获取myfunc的结果。如何更改myfunc,以便获得具有3列的新df?

编辑:

以下所有解决方案均有效。Series解决方案确实允许使用列名,而List解决方案的执行速度似乎更快。

def myfunc1(args):    e=args[0] + 2*args[1]    f=args[1]*args[2] +1    g=args[2] + args[0] * args[1]    return pd.Series([e,f,g], index=[''a'', ''b'', ''c''])def myfunc2(args):    e=args[0] + 2*args[1]    f=args[1]*args[2] +1    g=args[2] + args[0] * args[1]    return [e,f,g]%timeit df.apply(myfunc1 ,axis=1)100 loops, best of 3: 4.51 ms per loop%timeit df.apply(myfunc2 ,axis=1)100 loops, best of 3: 2.75 ms per loop

答案1

小编典典

只返回一个列表而不是元组。

In [81]: dfOut[81]:                             x         y         zts                                               2014-05-15 10:38:00  0.120117  0.987305  0.1162112014-05-15 10:39:00  0.117188  0.984375  0.1220702014-05-15 10:40:00  0.119141  0.987305  0.1191412014-05-15 10:41:00  0.116211  0.984375  0.1201172014-05-15 10:42:00  0.119141  0.983398  0.118164[5 rows x 3 columns]In [82]: def myfunc(args):   ....:        e=args[0] + 2*args[1]   ....:        f=args[1]*args[2] +1   ....:        g=args[2] + args[0] * args[1]   ....:        return [e,f,g]   ....:In [83]: df.apply(myfunc ,axis=1)Out[83]:                             x         y         zts                                               2014-05-15 10:38:00  2.094727  1.114736  0.2348032014-05-15 10:39:00  2.085938  1.120163  0.2374272014-05-15 10:40:00  2.093751  1.117629  0.2367702014-05-15 10:41:00  2.084961  1.118240  0.2345122014-05-15 10:42:00  2.085937  1.116202  0.235327

Pandas数据分析-pandas数据框的多层索引

Pandas数据分析-pandas数据框的多层索引

前言

pandas数据框针对高维数据,也有多层索引的办法去应对。多层数据一般长这个样子

可以看到AB两大列,下面又有xy两小列。 行有abc三行,又分为onetwo两小行。

在分组聚合的时候也会产生多层索引,下面演示一下。

导入包和数据:

import numpy as np 
import pandas as pd
df=pd.read_excel(''team.xlsx'')

分组聚合:

df.groupby([''team'',df.mean(1)>60]).count() #每组平均分大于60的人的个数

 可以看到分为abcde五组,平均分大于60 的组员两小行。

创建多层索引

#序列中创建
arrays = [[1, 1, 2, 2], [''red'', ''blue'', ''red'', ''blue'']]
index=pd.MultiIndex.from_arrays(arrays, names=(''number'', ''color''))
index

pd.DataFrame([{''a'':1, ''b'':2}], index=index)

#来自元组创建
arrays = [[''bar'', ''bar'', ''baz'', ''baz'', ''foo'', ''foo'', ''qux'', ''qux''],
          [''one'', ''two'', ''one'', ''two'', ''one'', ''two'', ''one'', ''two'']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=[''first'', ''second''])
pd.Series(np.random.randn(8), index=index)

#可迭代对象的笛卡尔积,排列组合各种情况
numbers = [0, 1, 2]
colors = [''green'', ''purple'']
index = pd.MultiIndex.from_product([numbers, colors],names=[''number'', ''color''])
pd.Series(np.random.randn(6), index=index)

#来自 DataFrame
df = pd.DataFrame([[''bar'', ''one''], [''bar'', ''two''],
                   [''foo'', ''one''], [''foo'', ''two'']],
                  columns=[''first'', ''second''])
''''''
  first second
0   bar    one
1   bar    two
2   foo    one
3   foo    two
''''''
index = pd.MultiIndex.from_frame(df)
pd.Series(np.random.randn(4), index=index)

 多层索引操作

index_arrays = [[1, 1, 2, 2], [''男'', ''女'', ''男'', ''女'']]
columns_arrays = [[''2020'', ''2020'', ''2021'', ''2021''],
                  [''上半年'', ''下半年'', ''上半年'', ''下半年'',]]
index = pd.MultiIndex.from_arrays(index_arrays,names=(''班级'', ''性别''))
columns = pd.MultiIndex.from_arrays(columns_arrays,names=(''年份'', ''学期''))
df = pd.DataFrame([(88,99,88,99),(77,88,97,98),
                   (67,89,54,78),(34,67,89,54)],columns=columns, index=index)
df

 索引名称的查看

#索引名称的查看:
df.index # 索引, 是一个 MultiIndex
df.columns # 引索引,也是一个 MultiIndex
# 查看行索引的名称
df.index.names # FrozenList([''班级'', ''性别''])
# 查看列索引的名称
df.columns.names # FrozenList([''年份'', ''学期''])

 索引的层级

#索引的层级:
df.index.nlevels # 层级数   2
df.index.levels # 行的层级    # FrozenList([[1, 2], [''女'', ''男'']])
df.columns.levels # 列的层级  # FrozenList([[''2020'', ''2021''], [''上半年'', ''下半年'']])
df[[''2020'',''2021'']].index.levels # 筛选后的层级  # FrozenList([[1, 2], [''女'', ''男'']])

 索引内容的查看

#索引内容的查看:
# 获取索引第2层内容
df.index.get_level_values(1)
# Index([''男'', ''女'', ''男'', ''女''], dtype=''object'', name=''性别'')
# 获取列索引第1层内容
df.columns.get_level_values(0)
# Index([''2020'', ''2020'', ''2021'', ''2021''], dtype=''object'', name=''年份'')
 
# 按索引名称取索引内容
df.index.get_level_values(''班级'')
# Int64Index([1, 1, 2, 2], dtype=''int64'', name=''班级'')
df.columns.get_level_values(''年份'')
# Index([''2020'', ''2020'', ''2021'', ''2021''], dtype=''object'', name=''年份'')
 
# 多层索引的数据类型,1.3.0+
df.index.dtypes

 #排序

# 使用索引名可进行排序,可以指定具体的列
df.sort_values(by=[''性别'', (''2020'',''下半年'')])
df.index.reorder_levels([1,0])  # 等级顺序,互换
df.index.set_codes([1, 1, 0, 0], level=''班级'') # 设置顺序
df.index.sortlevel(level=0, ascending=True)   # 按指定级别排序
df.index.reindex(df.index[::-1]) # 更换顺序,或者指定一个顺序

 相关操作转换:

df.index.to_numpy() # 生成一个笛卡尔积的元组对列表
# array([(1, ''男''), (1, ''女''), (2, ''男''), (2, ''女'')], dtype=object)
df.index.remove_unused_levels() # 返回没有使用的层级
df.swaplevel(0, 2) # 交换索引
df.to_frame() # 转为 DataFrame
idx.set_levels([''a'', ''b''], level=''bar'') # 设置新的索引内容
idx.set_levels([[''a'', ''b'', ''c''], [1, 2, 3, 4]], level=[0, 1])
idx.to_flat_index()   # 转为元组对列表
df.index.droplevel(0) # 删除指定等级
df.index.get_locs((2, ''女''))  # 返回索引的位置

数据查询

#查询指定行
df.loc[1] #一班的
df.loc[(1, ''男'')] # 一年级男
df.loc[1:2] # 一二两年级数据

#查询指定列
df[''2020''] # 整个一级索引下
df[(''2020'',''上半年'')] # 指定二级索引
df[''2020''][''上半年''] # 同上

#行列综合  slice(None)表示本层所有内容
df.loc[(1, ''男''), ''2020''] # 只显示2020年一年级男
df.loc[:, (slice(None), ''下半年'')] # 只看下半年的
df.loc[(slice(None), ''女''),:] # 只看女生
df.loc[1, (slice(None)),:] # 只看1班
df.loc[:, (''2020'', slice(None))] # 只看 2020 年的

#查询指定条件

#和单层索引的数据查询一样,不过在选择列上要按多层的规则。
df[df[(''2020'',''上半年'')] > 80]

#pd.IndexSlice切片使用:
 
idx = pd.IndexSlice
idx[0]               # 0
idx[:]               # slice(None, None, None)
idx[0,''x'']           # (0, ''x'')
idx[0:3]             # slice(0, 3, None)
idx[0.1:1.5]         # slice(0.1, 1.5, None)
idx[0:5,''x'':''y'']     # (slice(0, 5, None), slice(''x'', ''y'', None))
#查询应用:
idx = pd.IndexSlice
df.loc[idx[:,[''男'']],:] # 只显示男
df.loc[:,idx[:,[''上半年'']]] # 只显示上半年
 
#df.xs()
df.xs((1, ''男'')) # 一年级男生
df.xs(''2020'', axis=1) # 2020 年
df.xs(''男'', level=1) # 所有男生

 数据分组

df.groupby(level=0).sum()
df.groupby(level=''性别'').sum()
df.sum(level=''班级'') # 也可以直接统计

df.groupby(level=[''性别'', ''班级'']).sum()

到此这篇关于Pandas数据分析-andas数据框的多层索引的文章就介绍到这了,更多相关pandas多层索引内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:
  • Pandas将列表(List)转换为数据框(Dataframe)
  • Pandas 数据框增、删、改、查、去重、抽样基本操作方法
  • pandas数据框,统计某列数据对应的个数方法
  • python pandas创建多层索引MultiIndex的6种方式
  • Pandas的MultiIndex多层索引使用说明
  • pandas多层索引的创建和取值以及排序的实现
  • 在Pandas中给多层索引降级的方法

Pandas数据框按日期时间月份分组

Pandas数据框按日期时间月份分组

考虑一个csv文件:

string,date,number
a string,2/5/11 9:16am,1.0
a string,3/5/11 10:44pm,2.0
a string,4/22/11 12:07pm,3.0
a string,4/22/11 12:10pm,4.0
a string,4/29/11 11:59am,5/2/11 1:41pm,5/2/11 2:02pm,5/2/11 2:56pm,5/2/11 3:00pm,5.0
a string,5/2/14 3:02pm,6.0
a string,5/2/14 3:18pm,7.0

我可以阅读一下,然后将date列重新格式化为datetime格式:

b=pd.read_csv('b.dat')
b['date']=pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')

我一直在尝试按月对数据进行分组。似乎应该有一种明显的方式来访问月份并以此进行分组。但是我似乎做不到。有人知道吗?

我目前正在尝试按日期重新建立索引:

b.index=b['date']

我可以这样访问月份:

b.index.month

但是我似乎找不到一个可以按月汇总的函数。

今天关于通过pandas数据框按pandas ID中的两个日期之间的行数进行计数pandas根据时间筛选的讲解已经结束,谢谢您的阅读,如果想了解更多关于40期《Pandas数据处理与分析》|pandas基础笔记2|pandas 基础|joyfulPandas、pandas应用函数返回多个值到pandas数据帧中的行、Pandas数据分析-pandas数据框的多层索引、Pandas数据框按日期时间月份分组的相关知识,请在本站搜索。

本文标签: