pandas入门

pandas入门

pandas的数据结构介绍

Series

Series是一种类似于一维数组的对象,它由一组(类似NumPy数据类型的)数据以及一组与之相关的数据标签(即索引)组成。仅由一个数组即可创建最简单的Series:

obj = pd.Series([4,7,-5,3])
print(obj.array) # .array属性的结果是PandasArray对象,它通常封装了一个NumPy数组,但也可以包含特殊的扩展数组类型
print(obj.index)
# 经常需要创建带有索引的Series,用标签指明各个数据点
obj2 = pd.Series([4,7,-5,3],index=["d","b","a","c"])
print(obj2["d"])
obj2["d"]=6
print(obj2[["c","a","d"]]) # ["c", "a", "d"]是索引列表,它包含的是字符串而不是数字。

# 使用NumPy函数或类似NumPy的运算,比如用布尔型数组进行过滤、标量乘法、应用数学函数等,都会保留索引值的链接
print(obj2[obj2>0])
# d    6
# b    7
# c    3

# 还可以将Series看作长度固定的有序字典,因为它是索引值对数据值的映射。在可能使用字典的场景中,也可以使用Series:
print("d" in obj2)  # true

# 通过字典创建Series
sdata = {"Ohio":35000,"Texas":71000,"Oregon":16000,"Utah":5000}
obj3 = pd.Series(sdata)
# 通过to_dict方法,Series也可以转换回字典:
obj3.to_dict()
# 将字典键按照想要的顺序传给构造函数,从而使生成的Series的索引顺序符合你的预期
states = ["California","Oregon","Ohio","Texas"]
obj4 = pd.Series(sdata,index=states) # "California"没有对应的值,所以其结果为NaN,"Utah"不在states中,所以它会从结果中除去
# 检测缺失值
pd.isna(obj4)
pd.notna(obj4)
obj4.isna() # 也将其作为实例方法
obj4.notna()

# 在算数运算中能自动对齐索引标签
print(obj3+obj4)
# California         NaN
# Ohio           70000.0
# Oregon         32000.0
# Texas         142000.0
# Utah               NaN

# Series对象本身及其索引都有name属性
obj4.name="population"
obj4.index.name="state"
# Series的索引可以通过赋值的方式就地修改
obj4.index=["bob","steve","jeff","ryan"]

DataFrame

DataFrame是矩形的数据表,它含有一组有序且有命名的列,每一列可以是不同的数据类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,可以看作由共用同一个索引的Series组成的字典。

# 传入一个由等长列表或NumPy数组构成的字典
data = { 
    "state":["Ohio","Ohio","Ohio","Nevada","Nevada","Nevada"],
    "year":[2000,2001,2002,2001,2002,2003],
    "pop":[1.5,1.7,3.6,2.4,2.9,3.2]
}
frame=pd.DataFrame(data)
#     state  year  pop
# 0    Ohio  2000  1.5
# 1    Ohio  2001  1.7
# 2    Ohio  2002  3.6
# 3  Nevada  2001  2.4
# 4  Nevada  2002  2.9
# 5  Nevada  2003  3.2

# head方法会只选取前5行
frame.head()
# 获取最后5行
frame.tail()
# 按照指定顺序进行排列;如果字典不包含传入的列,就会在结果中产生缺失值
frame = pd.DataFrame(data,columns=["year","state","pop"])
#    year   state  pop
# 0  2000    Ohio  1.5
# 1  2001    Ohio  1.7
# 2  2002    Ohio  3.6
# 3  2001  Nevada  2.4
# 4  2002  Nevada  2.9
# 5  2003  Nevada  3.2

# 将DataFrame的列获取为一个Series
frame2["state"]  # 等价:frame2.state

# 通过iloc和loc属性,也可以通过位置或名称的方式进行获取行
sel2=frame2.loc[1]
sel3 = frame2.iloc[2]
# 修改值
frame2["year"]=16.5
frame2["year"]=np.arange(6)

# 将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,
# 它的标签就会精确匹配DataFrame的索引,所有的空缺都将填上缺失值
val = pd.Series([-1.2,-1.5,-1,7],index=["two","four","five"]) # 不存在的列会创建新列
frame2["debt"]=val
# 删除一列
del frame2["debt"]

# 如果将嵌套字典传给DataFrame,pandas就会将外层字典的键解释为列,将内层字典的键解释为行索引
populations = {
    "Obio":{2000:1.5,2001:1.7,2002:3.6},
    "Bvada":{2001:2.4,2002:2.9}
}
frame3 = pd.DataFrame(populations)
frame4 = pd.DataFrame(populations,index=[2001,2002,2003]) # 指定索引
#       Obio  Bvada
# 2000   1.5    NaN
# 2001   1.7    2.4
# 2002   3.6    2.9

# 使用类似NumPy数组的方法,可以对DataFrame进行转置(交换行和列
frame3.T

# 由Series组成的字典
pdata = {
    "Ohio":frame3["Ohio"][:-1],
    "Nevada":frame3["Nevada"][:2]
}
frame5 = pd.DataFrame(pdata)
可以向DataFrame构造器输入的数据
  • 二维ndarray:数据矩阵,传入可选的行标签和列标签
  • 由数组、列表或元组组成的字典:每个序列会变成DataFrame的一列,所有序列的长度必须相同
  • NumPy的结构化/记录化数组:处理方式与“由数组组成的字典”一致
  • 由Series组成的字典:每个值成为一列。如果没有显式指定索引,则各Series的索引会被合并成结果的行索引
  • 由字典组成的字典:各内部字典成为一列。键会被合并成结果的行索引,处理方式与“由Series组成的字典”一致
  • 字典或Series的列表:各项会成为DataFrame的一行。字典键或Series索引合并后成为DataFrame的列标签
  • 由列表或元组组成的列表:处理方式与“二维ndarray”一致
  • 另一个DataFrame:该DataFrame的索引将会被沿用,除非显式指定了其他索引
  • NumPy 的 MaskedArray:处理方式与“二维ndarray”一致,只是在DataFrame结果中缺少掩码值
# 设置了DataFrame的index和columns的name属性,则这些信息也会显示出来
# 不同于Series,DataFrame本身没有name属性
frame3.index.name="year"
frame3.columns.name="state"

# to_numpy方法将数据以二维ndarray的DataFrame形式返回
frame3.to_numpy()
# [[1.5 nan]
#  [1.7 2.4]
#  [3.6 2.9]]

索引对象

  • 与Python集合不同,pandas的索引可以包含重复的标签;选择重复的标签,会选取所有对应的结果
索引的方法和属性
  • append() 连接另一个索引对象,产生一个新的索引
  • difference() 计算差集,并得到一个索引
  • intersection() 计算交集
  • union() 计算并集
  • isin() 计算一个指示各值是否都包含在参数集合中的布尔型数组
  • delete() 删除索引处的元素,并得到新的索引
  • drop() 删除传入的值,并得到新的索引
  • insert() 将元素插入索引处,并得到新的索引
  • is_monotonic 当各元素均大于等于前一个元素时,返回True
  • is_unique 当索引没有重复值时,返回True
  • unique() 计算索引中唯一值的数组

基本功能

重建索引

# reindex,创建一个数据根据新索引重新排列的新对象
obj = pd.Series([4.5,7.2,-5.3,3.6],index=["d","b","a","c"])
# d    4.5
# b    7.2
# a   -5.3
# c    3.6
obj2 = obj.reindex(["a","b","c","d","e"])
# a   -5.3
# b    7.2
# c    3.6
# d    4.5
# e    NaN

# 对于时间序列这样的有序数据,重建索引时可能需要做一些插值或填值处理。method选项可以达到此目的
obj3 = pd.Series(["blue","purple","yellow"],index=[0,2,4])
obj3.reindex(np.arange(6),method="ffill") # 使用ffill可以实现前向填充值
# 0      blue
# 1      blue
# 2    purple
# 3    purple
# 4    yellow
# 5    yellow 

# frame reindex
frame = pd.DataFrame(np.arange(9).reshape((3,3)),
                     index=["a","b","c"],
                     columns=["Ohio","Texas","California"])
frame2 = frame.reindex(index=["a","b","c","d"])
# 用columns关键字重建索引
state = ["Texas","Utah","California"]
frame.reindex(columns=state)
frame.reindex(state,axis="columns") # 传入新的轴标签作为位置参数,然后用axis关键字对指定轴进行重建索引

# loc运算符重建索引,这也是多数人更为常用的方式
frame.loc[["a","d","c"],["California","Texas"]]
reindex函数的参数及说明
  • labels:用作索引的新序列。既可以是索引实例,也可以是其他序列型的Python数据结构。索引会被直接使用,无须复制
  • index:使用传入的序列作为新的索引标签
  • columns:使用传入的序列作为新的列标签axis进行重建索引的轴,可以是索引(行)也可以是列。默认为索引。既可以reindex(index=new_labels),也可以reindex(columns=new_labels)。
  • method:插值(填充)方式,“ffll”表示前向填充,"bfill"表示后向填充
  • fill-value:在重建索引的过程中导入了缺失值,用作替换的值。使用fill_value="missing”可以对结果中不存在的标签填入缺失值。
  • limit:前向或后向填充值时,最大的填充区间(以元素计数)
  • tolerance:前向或后向填充值时,填充不准确匹配项的最大区间(绝对值距离)
  • level:在多层索引的指定层级上匹配索引,否则选取其子集
  • copy:如果为True,即新索引等于旧索引l,总是复制底层数据;如果是False,则在索引相同时不复制数据

删除指定轴上的项

# drop方法返回的是一个在指定轴上删除了指定值的新对象
obj = pd.Series(np.arange(5.),index=["a","b","c","d","e"])
new_obj = obj.drop("c")
obj.drop(["d","c"])

# dataframe 删除
data = pd.DataFrame(np.arange(16).reshape((4,4)),
                    index=["Ohio","Colorado","Utah","New York"],
                    columns=["one","two","three","four"])
data.drop(index=["Colorado","Ohio"]) # 用标签序列调用drop会从行标签(axis 0)删除值:
data.drop(columns=["two"]) # 过传入columns关键字,可以删除列的标签
data.drop("two",axis=1) # 传入axis=1(类似于NumPy)或axis="columns",从列删除值
data.drop(["two","four"],axis="columns")

索引、选取和过滤

# Series索引(obj[...])的工作方式类似于NumPy数组的索引,只不过Series的索引值可以不仅仅是整数
obj = pd.Series(np.arange(4.),index=["a","b","c","d"])
print(obj["b"]) # 1.0
print(obj[1]) # 1.0
obj[2:4]
obj[["b","a","d"]]
obj[[1,3]]
obj[obj<2]

# 更可取的方式是使用特殊的loc运算符选取索引值
obj.loc[["b","a","d"]]

obj1 = pd.Series([1,2,3],index=[2,0,1])
print(obj1[[0,1,2]]) # 如果索引包含整数,常规的基于[]的索引会将整数用作标签
# 0    2
# 1    3
# 2    1

# 使用loc时,如果索引中不含整数,则表达式obj.loc[​[0, 1, 2]​]会失效:
obj2 = pd.Series([1,2,3],index=["a","b","c"])
obj2.loc[[0,1]] # KeyError
# loc运算符只使用标签,iloc运算符只使用整数。无论索引是否包含整数,都能使用iloc
obj1.iloc[[0,1,2]]
obj2.iloc[[0,1,2]]

# 还可以使用标签进行切片,但区别于普通Python的切片方式,loc的切片是包含末端的
obj2.loc["b":"c"]
# 使用以上切片方法可以对Series的相应部分进行赋值
obj2.loc["b","c"]=5
data = pd.DataFrame(np.arange(16).reshape((4,4)),
                    index=["Ohio","Colorado","Utah","New York"],
                    columns=["one","two","three","four"])
# 用单个值或序列对DataFrame进行索引,以获取单列或多列
data["two"]
data[["three","one"]]

# 通过切片或布尔型数组选取数据:
data[:2]
#           one  two  three  four
# Ohio        0    1      2     3
# Colorado    4    5      6     7
data[data["three"]>5]

# 它的所有值都是与一个标量比较得出的布尔值
data<5
#             one    two  three   four
# Ohio       True   True   True   True
# Colorado   True  False  False  False
# Utah      False  False  False  False
# New York  False  False  False  False

# 将0赋值给等于True的位置
data[data<5]=0

# DataFrame有两个特殊属性loc和iloc,分别用于标签索引和整数索引
data.loc["Colorado"] # 取出的单独一行是Series,它的索引是DataFrame的列标签
# one      4
# two      5
# three    6
# four     7

# 取多行,创建一个新的DataFrame,可以传入标签序列
data.loc[["Colorado","New York"]]
# 同时选取行和列
data.loc["Colorado",["two","three"]]

# iloc
data.iloc[2]
data.iloc[[2,1]]
data.iloc[2,[3,0,1]]
data.iloc[[1,2],[3,0,1]]

# 切片
data.loc[:"Utah","two"]
data.iloc[:,:3[data.three>5]]

# loc可以使用布尔型数组,但iloc不能使用
data.loc[data.three>=2]
DataFrame的索引选项
  • df[column]:从DataFrame选取单列或多列:在特殊情况下更为便利:布尔型数组(过滤行)、切片(行切片)、布尔型DataFrame(根据条件设置值)df.loc[rows]:通过标签,选取DataFrame的单行或多行
  • df.loc[:, cols]:通过标签,选取单列或多列
  • df.loc[rows, cols]:通过标签,同时选取行和列
  • df.iloc[rows]:通过整数索引l,从DataFrame选取单行或多行
  • df.iloc[:,cols]:通过整数索引1,选取单列或多列
  • df.iloc[rows, cols]:通过整数索引,同时选取行和列
  • df.at[row, col]:通过行和列标签,选取单个标量值
  • df.iat[row, col]:通过行和列的索引(整数),选取单个标量值reindex方法通过标签选取行或列

算术运算和数据对齐

s1 = pd.Series([7.3,-2.5,3.4,1.5],index=["a","c","d","e"])
s2 = pd.Series([-2.1,3.6,-1.5,4,3.1],index=["a","c","e","f","g"])
# 当将对象相加时,如果存在不同的索引对,则结果中的索引是所有索引的并集
print(s1+s2)
# a    5.2
# c    1.1
# d    NaN
# e    0.0
# f    NaN
# g    NaN

df1 = pd.DataFrame(np.arange(9.).reshape((3,3)),
                  columns=list("bcd"),
                  index=["Ohio","Texas","Colorado"])
df2 = pd.DataFrame(np.arange(12.).reshape((4,3)),
                   columns=list("bde"),
                   index=["Utah","Ohio","Texas","Oregon"])
# 相加后会返回DataFrame,其索引和列为原来两个DataFrame的并集
print(df1+df2)
#             b   c     d   e
# Colorado  NaN NaN   NaN NaN
# Ohio      3.0 NaN   6.0 NaN
# Oregon    NaN NaN   NaN NaN
# Texas     9.0 NaN  12.0 NaN
# Utah      NaN NaN   NaN NaN

# df2以及一个fill_value参数,用传入值替换运算中的缺失值
df1.add(df2,fill_value=0)
# 个方法都有一个以字母r开头的副本,会将参数翻转
1/df1 # 等价 df1.rdiv(1)

# 重建索引,也可以指定缺失值的默认值
df1.reindex(columns=df2.columns,fill_value=0)
灵活的算术方法
  • add、radd:加法(+)
  • sub、rsub:减法(-)
  • div、rdiv:除法(/)
  • floordiv、rfloordiv:底除(//)
  • mul、rmul:乘法(*)
  • pow、rpow:乘方(**)
# 当我们从arr减去arr[0]时,每一行都会执行这个操作,这就是广播机制
arr = np.arange(12.).reshape((3,4))
print(arr-arr[0])
# [[0. 0. 0. 0.]
#  [4. 4. 4. 4.]
#  [8. 8. 8. 8.]]

DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播:

frame = pd.DataFrame(np.arange(12.).reshape((4,3)),
                     columns=list("bde"),
                     index=["Utah","Ohio","Texas","Oregon"])
#           b     d     e
# Utah    0.0   1.0   2.0
# Ohio    3.0   4.0   5.0
# Texas   6.0   7.0   8.0
# Oregon  9.0  10.0  11.0
series = frame.iloc[0]
# b    0.0
# d    1.0
# e    2.0
frame-series
#           b    d    e
# Utah    0.0  0.0  0.0
# Ohio    3.0  3.0  3.0
# Texas   6.0  6.0  6.0
# Oregon  9.0  9.0  9.0

# 如果你希望在列上广播且匹配行,则必须使用算术运算方法并指定匹配索引:
series3 = frame["d"]
frame.sub(series3,axis="index")
函数应用和映射
frame = pd.DataFrame(np.random.standard_normal((4,3)),
                     columns=list("bde"),
                     index=["Utah","Ohio","Texas","Oregon"])
# NumPy的通用函数(元素级数组方法)也可用于操作pandas对象:
np.abs(frame)  # 每个取绝对值

另一个常见的操作是将函数应用到由各列或各行所形成的一维数组上。DataFrame的apply方法可以实现此功能:

def f1(x):
    return x.max()-x.min()
frame.apply(f1) # 这里的函数f计算了Series最大值和最小值的差,在frame的每列都执行了一次
frame.apply(f1,axis="columns") # 每行执行一次

# 传递到apply的函数不一定返回单个标量值,还可以返回由多个值组成的Series	
def f2(x):
    return pd.Series([x.min(),x.max()],index=["min","max"])
frame.apply(f2)

# 得到frame中各个浮点值的格式化字符串,使用applymap即可
def my_format(x):
    return f"{x:.2f}"
frame.applymap(my_format)

# 之所以叫作applymap,是因为Series有一个用于元素级函数的map方法
frame["e"].map(my_format)

排序和排名
obj = pd.Series(np.arange(4),index=["d","a","b","c"])
# 要对行或列标签按字典顺序排序,可使用sort_index方法,它将返回一个排好序的新对象
obj.sort_index()
# 按值进行排序,缺失值放到末尾
obj.sort_values()
# 缺失值放最前面
obj.sort_values(na_position="first")

# 对于DataFrame,可以根据任意一个轴上的索引进行排序
frame = pd.DataFrame(np.arange(8).reshape(2,4),
                     index=["three","one"],
                     columns=["d","a","b","c"])
frame.sort_index()
frame.sort_index(axis="columns")
# 默认升序,也可以降序
frame.sort_index(axis="columns",ascending=False)

# 当对DataFrame排序时,可以使用一列或多列中的数据作为排序键。
frame = pd.DataFrame({"b":[4,7,-3,2],"a":[0,1,0,1]})
frame.sort_values("b")
# 根据多个列进行排序
frame.sort_values(["a","b"])

# 排名从数组中的最小值开始,从1一直到数组中有效数据的数量
# rank是通过“为各组分配平均排名”的方式破坏平级关系的
obj=pd.Series([7,-5,7,4,2,0,4])
print(obj.rank())
# 0    6.5
# 1    1.0
# 2    6.5
# 3    4.5
# 4    3.0
# 5    2.0
# 6    4.5

# 根据值在原数据中出现的顺序给出排名
obj.rank(method="first") # 条目0和2没有使用平均排名6.5,它们被设成了6.0和7.0,因为数据中标签0位于标签2的前面
# 0    6.0
# 1    1.0
# 2    7.0
# 3    4.0
# 4    3.0
# 5    2.0
# 6    5.0

# 降序
obj.rank(ascending=False)
# 0    1.5
# 1    7.0
# 2    1.5
# 3    3.5
# 4    5.0
# 5    6.0
# 6    3.5

# DataFrame可以在行或列上计算排名
frame = pd.DataFrame({"b":[4.3,7,-3,2],"a":[0,1,0,1],"c":[-2,5,8,-205]})
frame.rank(axis="columns")

排名中打破平级关系的方法:

  • "averaget":默认:在每个组中分配平均排名
  • "min":对整组使用最小排名
  • "max":对整组使用最大排名
  • "first":按值在原始数据中出现的顺序分配排名
  • "dense":类似于method="min",但排名在组间增加1,而不是组中相等元素的数量
带有重复标签的轴索引
# 虽然许多pandas函数(如reindex)都要求标签唯一,但这并不是强制性的
obj = pd.Series(np.arange(5),index=["a","a","b","b","c"])
# 判断索引值是不是唯一
obj.index.is_unique
# 如果某个标签对应多个项,则返回Series
obj["a"]
# a    0
# a    1

# 对DataFrame的行(或列)进行索引时也是如此
df = pd.DataFrame(np.random.standard_normal((5,3)),
                  index=["a","a","b","b","c"])

描述性统计的汇总和计算

pandas对象拥有一组常用的数学和统计方法。它们大部分都属于约简或汇总统计,用于从Series中提取单个值(如sum或mean)或从DataFrame的行或列中提取Series。与对应的NumPy数组方法相比,它们都内置有处理缺失数据的功能

df = pd.DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],
                  index=["a","b","c","d"],
                  columns=["one","two"])
# 求和
df.sum()
# one    9.25
# two   -5.80

# 传入axis="columns"或axis=1会对各行进行跨列求和
df.sum(axis="columns")
# 不跳过na
df.sum(axis="index",skipna=False)
df.sum(axis="columns",skipna=False)
# mean,要求至少有一个非NA值
df.mean(axis="columns")

约简方法的常用选项:

  • axis:约简的轴,DataFrame的行用"index",列用“columns"
  • skipna:排除缺失值,默认为True
  • level如果轴是层次化索引l的(即Multilndex),则根据level分组约简
# 有些方法(如idxmin和idxmax)返回的是间接统计,比如达到最小值或最大值的索引
df.idxmax()
df.idxmin()
# 累积性,累加前面的
df.cumsum()
# a  1.40  NaN
# b  8.50 -4.5
# c   NaN  NaN
# d  9.25 -5.8

# describe会产生另外一种汇总统计
df.describe()
#             one       two
# count  3.000000  2.000000
# mean   3.083333 -2.900000
# std    3.493685  2.262742
# min    0.750000 -4.500000
# 25%    1.075000 -3.700000
# 50%    1.400000 -2.900000
# 75%    4.250000 -2.100000
# max    7.100000 -1.300000

# 对于非数值型数据,describe会产生另外一种汇总统计
obj = pd.Series(["a","a","b","c"]*4)
obj.describe()
# count     16
# unique     3
# top        a
# freq       8

描述性统计和汇总统计:

  • count:非NA值的数量
  • describe:计算汇总统计信息
  • min、max:计算最小值和最大值
  • argmin、argmax:计算最小值和最大值的索引位置(整数);在DataFrame对象上不可用
  • idxmin、idxmax:计算最小值和最大值的索引标签
  • quantile:计算样本0~1之间的分位数(默认为0.5)
  • SUM:所有值的总和mean所有值的平均数
  • median:所有值的算术中位数(50%分位数)
  • mad:平均值的平均绝对偏差
  • var:所有值的样本方差
  • std:所有值的样本标准差
  • skew:所有值的样本偏度(三阶矩)
  • kurt:所有值的样本峰度(四阶矩)
  • CumSum:所有值的累计和
  • cummin、cummax:所有值的累计最小值和累计最大值
  • cumprod:所有值的累计积
  • diff:计算一阶差分(对时间序列很有用)
  • pct change:计算百分比变化
相关系数与协方差(todo)
唯一值、计数以及成员属性
# unique,用于生成Series中的唯一值的数组
obj = pd.Series(["c","a","d","a","a","b","d","c","c"])
uniques = obj.unique()
# 排序
uniques.sort()
# 计算Series中各值出现的频次(频次降序排列)
obj.value_counts()
# value_counts是顶级的pandas方法,可用于NumPy数组或其他Python序列
pd.value_counts(obj.to_numpy,sort=False)

# isin 执行向量化的成员属性检查
obj = pd.Series(["c","a","d","a","a","b","d","c","c"])
mask = obj.isin(["b","c"])
# 0     True
# 1    False
# 2    False
# 3    False
# 4    False
# 5     True
# 6    False
# 7     True
# 8     True
obj[mask]
# 0    c
# 5    b
# 7    c
# 8    c

# Index.get_indexer方法,它可以提供一个索引数组,将可能包含重复值的数组转换为唯一值的数组
to_match = pd.Series(["c","a","b","b","c","a"])
unique_vals = pd.Series(["c","b","a"])
# 索引位置
indices = pd.Index(unique_vals).get_indexer(to_match) # [0 2 1 1 0 2]

唯一值、计数、成员属性方法:

  • isin:计算表示Series各值是否包含于传入序列的布尔型数组
  • match:计算数组中的各值到另一个唯一值数组的整数索引,对于数据对齐和连接类型的操作十分有用
  • unique:计算Series中的唯一值数组,按发现的顺序返回
  • value_counts:返回一个Series,唯一值作为索引l,频次作为值,频次按降序排列
data = pd.DataFrame({"Qu1":[1,3,4,3,4],
                     "Qu2":[2,3,1,2,3],
                     "Qu3":[1,5,2,4,4]})
# 计算其中一列的计数  就是上面的series
data["Qu1"].value_counts().sort_index()
# 计算所有列的计数,每列中不同值的相应计数
result = data.apply(pd.value_counts).fillna(0)
#    Qu1  Qu2  Qu3
# 1  1.0  1.0  1.0
# 2  0.0  2.0  1.0
# 3  2.0  2.0  0.0
# 4  2.0  0.0  2.0
# 5  0.0  0.0  1.0

# 将DataFrame的每行当作元组,计算不同行的计数
data = pd.DataFrame({"a":[1,1,1,2,2],"b":[0,0,1,0,0]})
data.value_counts()
# a  b
# 1  0    2
# 2  0    2
# 1  1    1
posted @ 2025-04-20 10:42  huihui_teresa  阅读(5)  评论(0)    收藏  举报