文章目录
pandas常用统计方法
例题1
假设现在我们有一组从2006年到2016年1000部最流行的电影数据,我们想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?
部分数据如下:
Rank | Title | Genre | Description | Director | Actors | Year | Runtime (Minutes) | Rating | Votes | Revenue (Millions) | Metascore |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | Guardians of the Galaxy | Action,Adventure,Sci-Fi | .。。。 | James Gunn | Chris Pratt, Vin Diesel, Bradley Cooper, Zoe Saldana | 2014 | 121 | 8.1 | 757074 | 333.13 | 76 |
2 | Prometheus | Adventure,Mystery,Sci-Fi | 。。。 | Ridley Scott | Noomi Rapace, Logan Marshall-Green, Michael Fassbender, Charlize Theron | 2012 | 124 | 7 | 485820 | 126.46 | 65 |
3 | Split | Horror,Thriller | 。。。 | M. Night Shyamalan | James McAvoy, Anya Taylor-Joy, Haley Lu Richardson, Jessica Sula | 2016 | 117 | 7.3 | 157606 | 138.12 | 62 |
4 | Sing | Animation,Comedy,Family | 。。。 | Christophe Lourdelet | Matthew McConaughey,Reese Witherspoon, Seth MacFarlane, Scarlett Johansson | 2016 | 108 | 7.2 | 60545 | 270.32 | 59 |
5 | Suicide Squad | Action,Adventure,Fantasy | 。。。 | David Ayer | Will Smith, Jared Leto, Margot Robbie, Viola Davis | 2016 | 123 | 6.2 | 393727 | 325.02 | 40 |
import pandas as pd
import numpy as np
file_path = "IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
# print(df.info())
print(df.head(1))
#获取平均评分
print(df["Rating"].mean())
#导演的人数
# print(len(set(df["Director"].tolist())))
print(len(df["Director"].unique()))
#获取演员的人数
temp_actors_list = df["Actors"].str.split(", ").tolist()
actors_list = [i for j in temp_actors_list for i in j]
actors_num = len(set(actors_list))
print(actors_num)
例题2
对于这一组电影数据,如果我们想rating,runtime的分布情况,应该如何呈现数据?
import pandas as pd
import matplotlib.pyplot as plt
file_path = r"C:\Users\zouyo\Desktop\IMDB-Movie-Data.csv"
t1 = pd.read_csv(file_path)
print(t1.head(5))
print(t1.info())
def tu1():
runtime_data = t1["Runtime (Minutes)"].values
# 计算组数
num = (runtime_data.max()-runtime_data.min())//5
# 设置图形大小
plt.figure(figsize=(16,8),dpi=80)
plt.hist(runtime_data,num)
plt.xticks(range(runtime_data.min(),runtime_data.max()+5,5))
plt.show()
def tu2():
runtime_data = t1["Rating"].values
# 计算组数
num = int((runtime_data.max() - runtime_data.min()) // 0.5)
print(runtime_data.min(),runtime_data.max())
num1 = [1.9+i*0.5 for i in range(0, int(num+1))]
print(num1)
# 设置图形大小
plt.figure(figsize=(16, 8), dpi=80)
plt.hist(runtime_data,num)
plt.xticks(num1)
plt.show()
tu1()
tu2()
这里的第二幅图的X坐标对不上,始终没有解决。
例题3
统计每种电影类型的数量,并画出图形。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 读取CSV文件内容
file_path = r"C:\Users\zouyo\Desktop\IMDB-Movie-Data1.csv"
t1 = pd.read_csv(file_path)
# 将Genre列中的内容以字符串形式处理,用split方法分开,组成一个二维列表
Genre = t1["Genre"].str.split(",").tolist()
# 将Genre这个二维数组合并成一个一维数组
Genre1 = [i for j in Genre for i in j]
# 去重,并转换成列表形式
x = list(set(Genre1))
# 建立一个Dataframe对象,相当于一个表格,当电影属于某一类型标记为1,不是某一类为0
y = pd.DataFrame(np.zeros((len(Genre), len(x)), int), index=t1["Title"], columns=x)
k = 0
for i in Genre:
y.loc[t1["Title"][k], i] = 1
k += 1
# 将每一种电影类型的数量统计出来
Genre_count = y.sum(axis=0)
print(Genre_count)
# 排序
Genre_count = Genre_count.sort_values()
_x = Genre_count.index
_y = Genre_count.values
# 画一个简易条形图
plt.figure(figsize=(16, 8), dpi=80)
plt.barh(range(len(_x)), _y, height=0.5, color="orange")
plt.yticks(range(len(_x)), _x)
plt.show()
数据合并
数据合并之join
join:默认情况下他是把行索引相同的数据合并到一起
如果是t2.join(t1), 则左边是t2,右边是t1,且t1没有C行。
数据合并之merge
merge:按照指定的列把数据按照一定的方式合并到一起
- 默认的合并方式inner,交集
- how=“outer”,并集,NaN补全
- how=“left”,左边为准,NaN补全
- how=“right”,右边为准,NaN补全
数组分组聚合
例题
现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克的数量和中国的哪个多,或者我想知道中国每个省份星巴克的数量的情况,那么应该怎么办?
数据的分组(groupyby)
创建DataFrame对象
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
'a', 'b', 'a', 'a'],
'key2' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'data1': np.random.randn(8),
'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
print(df_obj)
data1 data2 key1 key2
0 1.614626 -1.571301 a one
1 0.460157 0.041038 b one
2 -2.070866 -0.885139 a two
3 0.770066 0.278396 b three
4 0.040073 -1.834590 a two
5 -0.105759 -0.115968 b two
6 0.442917 -1.719780 a one
7 1.368152 -0.798185 a three
## 1. 分组操作,创建groupby对象
# 如果对整个数据集进行分组,groupby参数直接指定列名即可
grouped = df_obj.groupby("key2")
print(grouped)
<pandas.core.groupby.DataFrameGroupBy object at 0x00000134964429E8>
# 2. 分组运算,对groupby对象进行运算
## 在分组的基础上,对分组对象调用方法进行运算
## 注意:分组运算只会作用于数据部分,非数据部分不参与运算
print(grouped.sum())
data1 data2
key2
one 2.517700 -3.250042
three 2.138218 -0.519789
two -2.136552 -2.835698
# 如果对单独某个数据部分的列进行分组运算,那么groupby的参数必须指定数据集的某一列进行分组
grouped2 = df_obj["data2"].groupby(df_obj["key2"])
grouped2.mean()
key2
one -1.083347
three -0.259895
two -0.945233
Name: data2, dtype: float64
# 3. 自定义分组运算
# 如果现有的分组不满足业务需求,可以自己创建一个分组规则,实现数据分组运算
self_key = ["aa", "bb", "cc", "dd", "aa", "bb", "cc", "dd"]
grouped3 = df_obj.groupby(self_key)
grouped3.sum()
data1 data2
aa 1.654699 -3.405891
bb 0.354398 -0.074930
cc -1.627948 -2.604919
dd 2.138218 -0.519789
# 4. 多层分组,索引顺序按列表里的参数顺序来决定
#print(df_obj)
grouped4 = df_obj.groupby(["key2", "key1"])
#grouped4 = df_obj["data1"].groupby([df_obj["key2"], df_obj["key1"]])
grouped4.sum()
data1 data2
key2 key1
one a 2.057543 -3.291080
b 0.460157 0.041038
three a 1.368152 -0.798185
b 0.770066 0.278396
two a -2.030793 -2.719729
b -0.105759 -0.115968
groupby 支持迭代操作
grouped4 = df_obj.groupby(["key2", "key1"])
#print(grouped4)
for name, data in grouped4:
print(name)
print(data)
('one', 'a')
data1 data2 key1 key2
0 1.614626 -1.571301 a one
6 0.442917 -1.719780 a one
('one', 'b')
data1 data2 key1 key2
1 0.460157 0.041038 b one
('three', 'a')
data1 data2 key1 key2
7 1.368152 -0.798185 a three
('three', 'b')
data1 data2 key1 key2
3 0.770066 0.278396 b three
('two', 'a')
data1 data2 key1 key2
2 -2.070866 -0.885139 a two
4 0.040073 -1.834590 a two
('two', 'b')
data1 data2 key1 key2
5 -0.105759 -0.115968 b two
## GroupBy对象可以直接转换为字典和列表
print(list(grouped4))
print(dict(list(grouped4)))
## 桉数据类型分组
print(df_obj.dtypes)
# 可以通过数据类型分组,默认是按列,axis=1 表示轴方向为行
print(df_obj.groupby(df_obj.dtypes, axis = 1).size())
(('one', 'b'), data1 data2 key1 key2
1 0.460157 0.041038 b one)
{('one', 'a'): data1 data2 key1 key2
0 1.614626 -1.571301 a one
6 0.442917 -1.719780 a one, ('one', 'b'): data1 data2 key1 key2
1 0.460157 0.041038 b one, ('three', 'a'): data1 data2 key1 key2
7 1.368152 -0.798185 a three, ('three', 'b'): data1 data2 key1 key2
3 0.770066 0.278396 b three, ('two', 'a'): data1 data2 key1 key2
2 -2.070866 -0.885139 a two
4 0.040073 -1.834590 a two, ('two', 'b'): data1 data2 key1 key2
5 -0.105759 -0.115968 b two}
data1 float64
data2 float64
key1 object
key2 object
dtype: object
float64 2
object 2
dtype: int64
# 构建一个数据部分区间为 1~10的5行5列, 行索引是 index列表, 列索引是 columns 列表
df_obj2 = pd.DataFrame(np.random.randint(1, 10, (5,5)),
columns=['a', 'b', 'c', 'd', 'e'],
index=['A', 'B', 'C', 'D', 'E'])
# 给指定某个部分的数据重新赋值为 np.NaN
df_obj2.ix[1, 1:4] = np.NaN
print(df_obj2)
## 按字典分组
dic = {"a" : "C++", "b": "Python", "c" : "Java", "d" : "PHP", "e" : "C#"}
print(df_obj2.groupby(dic, axis = 1).size())
a b c d e
A 7 3.0 6.0 7.0 4
B 8 NaN NaN NaN 7
C 4 4.0 5.0 9.0 8
D 7 3.0 3.0 2.0 3
E 4 8.0 6.0 8.0 5
C# 1
C++ 1
Java 1
PHP 1
Python 1
dtype: int64
# 通过自定义函数分组
def group_key(idx):
"""
idx 为列索引或行索引
"""
#return idx
return len(idx)
#print(df_obj2.groupby(group_key, axis=1).sum())
print(df_obj2.groupby(len, axis = 1).sum())
1
A 27.0
B 15.0
C 30.0
D 18.0
E 31.0
# 通过层级索引来分组
columns = pd.MultiIndex.from_arrays([['Python', 'Java', 'Python', 'Java', 'Python'],
['A', 'A', 'B', 'C', 'B']], names=['language', 'index'])
df_obj4 = pd.DataFrame(np.random.randint(1, 10, (5, 5)), columns=columns)
print(df_obj4)
#print(df_obj4.groupby(level ="index", axis=1).sum())
print(df_obj4.groupby(level ="language", axis=1).sum())
language Python Java Python Java Python
index A A B C B
0 5 2 6 7 9
1 1 2 2 2 2
2 1 2 3 9 3
3 4 5 5 7 6
4 6 7 1 6 7
language Java Python
0 9 20
1 4 5
2 11 7
3 12 15
4 13 14
数据的聚合
import pandas as pd
import numpy as np
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
'a', 'b', 'a', 'a'],
'key2' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'data1': np.random.randint(1,10, 8),
'data2': np.random.randint(1,10, 8)}
df_obj = pd.DataFrame(dict_obj)
print(df_obj)
# 1. 常用的内置聚合函数
#print(df_obj.groupby("key1").sum())
#print(df_obj.groupby("key1").max())
#print(df_obj.groupby("key1").min())
#print(df_obj.groupby("key1").mean())
print(df_obj.groupby("key1").describe())
# 2. 调用自定义聚合函数 做聚合运算
# 函数作用:最大值和最小值的差
def func(num):
return num.max() - num.min()
print(df_obj.groupby("key2").agg(func))
# 3. 调用多个聚合函数做聚合运算
#注意:调用多个函数使用列表将函数放在一起,如果是内置聚合函数则用字符串表示 ,自定义函数直接写函数名
print(df_obj.groupby("key1").agg(["sum", "mean", "max", func]))
# 多不同数据使用不同的聚合函数
# 每列作用不同的聚合函数
dict_mapping = {'data1':'mean',
'data2':'sum'}
print(df_obj.groupby('key1').agg(dict_mapping))
# 如果某一列使用多个聚合函数,参数是列表
dict_mapping = {'data1':'mean',
'data2':['sum', 'mean', func]}
print(df_obj.groupby('key1').agg(dict_mapping))
# 输出
data1 data2 key1 key2
0 7 8 a one
1 2 1 b one
2 7 5 a two
3 9 5 b three
4 6 4 a two
5 3 6 b two
6 8 7 a one
7 6 1 a three
data1 data2
key1
a count 5.000000 5.000000
mean 6.800000 5.000000
std 0.836660 2.738613
min 6.000000 1.000000
25% 6.000000 4.000000
50% 7.000000 5.000000
75% 7.000000 7.000000
max 8.000000 8.000000
b count 3.000000 3.000000
mean 4.666667 4.000000
std 3.785939 2.645751
min 2.000000 1.000000
25% 2.500000 3.000000
50% 3.000000 5.000000
75% 6.000000 5.500000
max 9.000000 6.000000
data1 data2
key2
one 6 7
three 3 4
two 4 2
data1 data2
sum mean max func sum mean max func
key1
a 34 6.800000 8 2 25 5 8 7
b 14 4.666667 9 7 12 4 6 5
data1 data2
key1
a 6.800000 25
b 4.666667 12
data1 data2
mean sum mean func
key1
a 6.800000 25 5 7
b 4.666667 12 4 5
索引和复合索引
简单索引
简单的索引操作:
- 获取index:df.index指定index :df.index = [‘x’,‘y’]
- 重新设置index : df.reindex(list(“abcedf”))
- 指定某一列作为index :df.set_index(“Country”,drop=False)
- 返回index的唯一值:df.set_index(“Country”).index.unique()
Series复合索引
只想取索引h对应值