Pandas 中的数据探索
整体探索:
data.columns.values # 查看有哪些列
data.keys() # 查看有哪些列
data.describe() # 描述性统计
data.head(2).T # 查看前2行
data.shape # 查看dataframe的形状,是几行几列的
type(data[item][2]) # 查看某一个变量的数据类型
data.preferred_genre.value_counts() # 查看一个feature的每一种取值有多少样本
data.info()
查看DataFrame总共有多少行、多少列:
# 返回列数:
df.shape[1]
# 返回行数:
df.shape[0]
# 或者:
len(df)
查看每一列的空值数:
df.isna().sum()
判断一个对象是否为空值:
pd.isnull(na) # True
pd.isna(na) # True
np.isnan(na) # True
na is np.nan # True
na in [np.nan] # True
# 注意,不能用==np.nan来判断
查看一个feature的不重复值有哪些、数据类型、空值个数:
def unique(data,i):
variables = data.keys().values
item = variables[i]
print(sorted(data[item].unique()))
except:
print(data[item].unique())
print('-'*5, item, '-'*5)
print(type(data[item][0]))
print('-'*5, data[item].isna().sum(), '-'*5)
提取值:
dataframe_name.iloc[1:3,2:]
注意,通过冒号前后数字的不同组合,可以提取出来不同的样式。
例如,我们同样是从DataFrame中仅仅提取一个值出来,有可能提取出来字符串、pd.Series、pd.DataFrame三种格式的数据。
首先,我们创建一个用于示范的DataFrame:
data = {'水果':['苹果','梨','草莓'],
'数量':[3,2,5],
'价格':[10,9,8]}
data = pd.DataFrame(data)
然后,我们指定要提取的是第几行、第几列:
j = 2 # 行
i = 0 # 列
下面我们开始提取处于该位置的数据。
第一种方法:直接指定坐标
output1 = data.iloc[j, i]
print(output1)
print(type(output1))
我们发现,仅仅是把处于这个位置的值提取出来了,且数据类型为字符串型。
第二种方法:行号指定成一个区间,列号指定成一个数字
output2 = data.iloc[j:j+1, i]
print(output2)
print(type(output2))
此时,由于行号是一个区间,我们的目光会在同一列中,从上到下由区间开头扫到区间结尾。因此提取出来的是一个pd.Series,且Series的name是该列的列名。
第三种方法:行号指定成一个数字,列号指定成一个区间
output3 = data.iloc[j, i:i+1]
print(output3)
print(type(output3))
此时,由于列号是一个区间,我们的目光会在同一行中,从左到右由区间开头扫到区间结尾。因此提取出来的是一个pd.Series,且Series的name是该行的行名。
第四种方法:行号和列号均指定成一个区间。
output4 = data.iloc[j:j+1, i:i+1]
print(output4)
print(type(output4))
根据上面的两个关于提取成Series的例子,我们就可以类推出这种情况,提取出来的是一个DataFrame。即使我们只提取了一个数据出来。
这里有一个要注意的地方,对于切片的修改会应用到原DataFrame上。
例如,下面我们做一个切片,
data_v = data.iloc[:,:]
然后对切片进行修改
data_v.iloc[2,2] = 2000
我们会发现,原DataFrame的值也变了。
所以,不能用这种方法来备份一个DataFrame。
正确的方法是用DataFrame的copy方法。
根据索引值提取DataFrame的一列,或者根据索引值提取Series的一个值:
dateframe_name[column_name]
dateframe_name[column_name_list1+column_name_list2]
data.column_name
# 这两种提取列的方法返回的内容是一样的
注意,在上面的方括号中,如果方括号内写的是一连串的字符串,name是只能按照column_name提取。如果写的一连串的True和False,那么是按照行提取的。
统计每一个组合有多少种情况:
data.value_counts()
# 注意,value_counts()不仅仅只能统计dataframe或者series里面的元素,对于列表里面的元素也是可以统计的。
# 例如,我们要统计sample=[1,2,3,2,1,4,1,1,2,5,3]中,每一个元素出现了几次,可以写:
pd.value_counts(sample)
提取一个dataframe里面,某一列的值不为0的所有的行:
dataframe.loc[dataframe.column_name != '0']
# 这一行的效果是,如果这个dataframe的这一列里面的某一个值为0,那么这一整行都会被剔除
# 取非的另一种方法是用~符号,注意,~符号后面的内容要用括号括起来,原因是~号的运算优先级大于==号
df = df[~(df.rumormongerName=="")]
查看index有没有重复值:
type1.index.is_unique
判断一个值是否是NaN:
dataframe_name.iloc[i,j] is np.nan
查看一个Series有哪些不重复的值:
dataframe.column_name.unique()
# 这一行,会把一个series里面所有可能出现的值列出来。
用index或column来筛选:
df_Tableau.filter(like = "Total", axis = 0)
# axis=0表示对于index筛选,axis=1表示用column筛选
# 用来筛选的指标可以用item、like、regex来控制
# item表示必须完全匹配label
# like表示label中包含这个指标即可,不必完全相同
# regex表示用正则表达式匹配
对于index或者column更加复杂的筛选,可以用一些自己定义的函数,对于column或者index name进行筛选,然后通过column names进行提取。
columns_needed = [item for item in data.columns.to_list() if 'Cusine' in item or 'SpendNew' in item or 'CityLevelNew_' in item or 'context_1119' in item]
用某一列的值来筛选dataframe:
# 法一:
data[data['price'].values<=5000]
# 筛选data里面,price小于等于5000的所有observation。
# 这里面,<=符号也可以换成>=、==、!=等判断符号。
# 如果有多个条件,若多个条件时间是或的关系要用“|”而不能用or;
# 同理是和的关系要用“&”。且每一个条件用小括号括起来;
# 上面两句的原因是:对于逻辑运算符,比如 b1 and b2,python里等价于bool(b1) and bool(b2),但是对于bool Series,直接bool(bool Series)是不行的,就会出现上述错误,因为无法直接对一个Series使用bool函数。所以,我们要用位运算符来实现。pandas中,位运算符是类似于加减法这些运算的,因此直接对两个Series使用位运算符,就等价于对两个Series的相应位置的元素进行位运算
# 例如:data[(data['payment_period']==0) & (data['trial_completed']==False)]
# 法二:
data.query('courier_id==10007871')
# 用id来查询数据
# 法三: