Pandas是一种数据分析工具,是Python中非常流行的库之一,主要用于数据清洗、数据转换、数据分析和数据可视化。Pandas提供了两种重要的数据结构,分别是Series(一维的数据结构)和DataFrame(二维的数据结构)。
Pandas的功能包括:
下面是一个示例,首先需要安装pandas库:
pip install pandas
导入库并创建一个DataFrame:
import pandas as pd
data = {'name': ['Alice', 'Bob', 'Charlie', 'David'],
'age': [25, 32, 18, 47],
'gender': ['F', 'M', 'M', 'M'],
'salary': [5000, 8000, 3500, 6000]}
df = pd.DataFrame(data)
查看DataFrame的数据:
print(df)
输出结果如下:
name age gender salary
0 Alice 25 F 5000
1 Bob 32 M 8000
2 Charlie 18 M 3500
3 David 47 M 6000
对数据进行描述统计分析:
print(df.describe())
输出结果如下:
age salary
count 4.000000 4.000000
mean 30.500000 5625.000000
std 11.225255 2062.048144
min 18.000000 3500.000000
25% 23.250000 4625.000000
50% 28.500000 5500.000000
75% 35.750000 6500.000000
max 47.000000 8000.000000
对数据进行透视表分析:
pivot = df.pivot_table(index='gender', values='salary', aggfunc='mean')
print(pivot)
输出结果如下:
salary
gender
F 5000
M 5833
对数据进行数据清洗:
df.drop_duplicates(inplace=True)
df.dropna(inplace=True)
上述代码删除了DataFrame中的重复值和空值。
最后,可以将数据导出到Excel文件中:
df.to_excel('data.xlsx', index=False)
使用Pandas按列排序更具可读性,如下所示:
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
np_data=np.array([[1,10,100],[2,20,150],[3,15,200],[4,15,80]])
df_data = pd.DataFrame([[1,10,100],[2,20,150],[3,15,200],[4,15,80]],columns=['id','price','weight'],dtype=float)
#----------------------------np排序----------------------------
np_data=np_data[np.argsort(np_data[:,1])]
print(np_data)
print('---------------------------------------------------------')
#----------------------------pd排序----------------------------
df_data=df_data.sort_values('price')
print(df_data)
这里argsort(a[:,1])计算使a的第二列按升序排序的排列,然后a[…]相应地对a的行重新排序。Pandas可以一步完成。
如果我们需要使用weight列来对价格列进行排序,情况会变得更糟。这里有几个例子来说明我们的观点:
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
np_data=np.array([[1,10,100],[2,20,150],[3,15,200],[4,15,80]])
df_data = pd.DataFrame([[1,10,100],[2,20,150],[3,15,200],[4,15,80]],columns=['id','price','weight'],dtype=float)
#----------------------------np排序----------------------------
np_data=np_data[np.argsort(np_data[:,2])]
np_data=np_data[np.argsort(np_data[:,1],kind='stable')]
print(np_data)
print('---------------------------------------------------------')
#----------------------------pd排序----------------------------
df_data=df_data.sort_values(['price','weight'])
print(df_data)
在NumPy中,我们先按重量排序,然后再按价格排序。稳定排序算法保证第一次排序的结果不会在第二次排序期间丢失。NumPy还有其他实现方法,但没有一种方法像Pandas那样简单优雅。
使用Pandas添加列在语法和架构上要好得多。下面的例子展示了如何操作:
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
np_data=np.array([[1,10,100],[2,20,150],[3,15,200],[4,15,80]])
df_data = pd.DataFrame([[1,10,100],[2,20,150],[3,15,200],[4,15,80]],columns=['id','price','weight'],dtype=float)
#----------------------------np添加列----------------------------
np_data=np.column_stack((np_data,np_data[:,1]/np_data[:,2]))
print(np_data)
print('---------------------------------------------------------')
#----------------------------pd添加列----------------------------
df_data['price_pre_gram']=df_data.price/df_data.weight
print(df_data)
Pandas不需要像NumPy那样为整个数组重新分配内存;它只是添加了对新列的引用,并更新了列名的registry
。
在NumPy数组中,即使你查找的是第一个元素,你仍然需要与数组大小成正比的时间来查找它。使用Pandas,你可以索引你期望被查询最多的列,并将搜索时间减少到一个常量。
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
np_data=np.array([[100,10,100],[314,20,150],[213,15,200],[432,15,80]])
df_data = pd.DataFrame([[100,10,100],[314,20,150],[213,15,200],[432,15,80]],columns=['id','price','weight'],dtype=float)
#----------------------------np添加列----------------------------
value=np_data[np.where(np_data==213)[0][0]][2] # 时间复杂度 O(N)
print(value)
print('---------------------------------------------------------')
#----------------------------pd添加列----------------------------
value=df_data.loc[df_data.id==213,'weight'].item() # 时间复杂度 O(N)
print(value)
df_data.set_index('id',inplace=True)
value=df_data.loc[213,'weight'] # 时间复杂度 O(1)
df_data.reset_index(inplace=True)
print(value)
index列有以下限制。
如果你想从另一张表中获取基于同一列的信息,NumPy几乎没有任何帮助。Pandas更好,特别是对于1:n的关系。
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
sales = pd.DataFrame([['John',1],['Silvia',3],['Andrew',1]],columns=['client','product_id'],dtype=float)
products = pd.DataFrame([[1,'banana'],[2,'apple'],[3,'orange']],columns=['id','name'],dtype=float)
#----------------------------pd添加列----------------------------
value=sales.join(products.set_index('id'),on='product_id')
print(value)
Pandas join具有所有熟悉的“内”、“左”、“右”和“全外部”连接模式。
数据分析中的另一个常见操作是按列分组。例如,要获得每种产品的总销量,你可以这样做:
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
sales = pd.DataFrame([['John',1,5],['Silvia',3,3],['Andrew',1,4]],columns=['client','product_id','quantity'],dtype=float)
products = pd.DataFrame([[1,'banana'],[2,'apple'],[3,'orange']],columns=['id','name'],dtype=float)
#----------------------------pd添加列----------------------------
# join
value=sales.join(products.set_index('id'),on='product_id')
print(value)
# group
value=value.groupby('name',as_index=False).sum('quantity')
print(value)
除了sum之外,Pandas还支持各种聚合函数:mean、max、min、count等。
Pandas最强大的功能之一是“枢轴”表。这有点像将多维空间投影到二维平面上。
import numpy as np
import pandas as pd
#----------------------------数据----------------------------
sales = pd.DataFrame([['John','bananas',5],['John','oranges',3],['Silvia','bananas',4],['Silvia','oranges',2]],columns=['client','product','quantity'],dtype=float)
#----------------------------pd添加列----------------------------
pivot_value=sales.pivot(index='client',columns='product',values='quantity')
print(pivot_value)
虽然用NumPy当然可以实现它,但这个功能没有开箱即用,尽管它存在于所有主要的关系数据库和电子表格应用程序(Excel,WPS)中。
Pandas用df.pivot_table将分组和旋转结合在一个工具中。
简而言之,NumPy和Pandas的两个主要区别如下:
对于小数组(少于100行),Pandas似乎比NumPy慢30倍,对于大数组(超过100万行)则慢3倍。
Pandas在这些基本操作方面非常缓慢,因为它正确地处理了缺失值。Pandas需要NaNs (not-a-number)来实现所有这些类似数据库的机制,比如分组和旋转,而且这在现实世界中是很常见的。在Pandas中,我们做了大量工作来统一所有支持的数据类型对NaN的使用。根据定义(在CPU级别上强制执行),nan+anything会得到nan。所以
>>> np.sum([1, np.nan, 2])
nan
但是
>>> pd.Series([1, np.nan, 2]).sum()
3.0
一个公平的比较是使用np.nansum代替np.sum,用np.nanmean而不是np.mean等等。
对于超过100万个元素的数组,Pandas的速度是NumPy的1.5倍。对于较小的数组,它仍然比NumPy慢15倍,但通常情况下,无论操作在0.5 ms还是0.05 ms内完成都没有太大关系——无论如何它都是快速的。
对于超过100万个元素的数组,Pandas的速度是NumPy的1.5倍。对于较小的数组,它仍然比NumPy慢15倍,但通常情况下,无论操作在0.5 ms还是0.05 ms内完成都没有太大关系——无论如何它都是快速的。