Pandas 使用

3 minute read

Published:

数据导入

pd.read_csv()

skiprows: 在文件开头需要跳过的行号或者行数

pd.read_json()

orient(): 设定预期的JSON字符串格式。orient可以理解为“识别”,可能的识别格式为:

  • ‘split’ : dict like {index -> [index], columns -> [columns], data -> [values]}
  • ‘records’ : list like [{column -> value}, … , {column -> value}]
  • ‘index’ : dict like {index -> {column -> value}}、
  • ‘columns’ : dict like {column -> {index -> value}}
  • ‘values’ : just the values array

    检查数据

  • pd.head() 展示前几行
  • pd.info() 展示每列的信息如数据类型,缺失数据的个数等

image.png

  • pd.describe() 返回每一列的统计信息

image.png

  • pd.shape 返回DataFrame的行数和列数

    set_index,sort_index,reindex,reset_index()

    set_index()

    set_index()将pandas的某一列作为索引。 如果是多重索引则将列名以列表的形式传入。 比如名字为df的DataFrame: image.png data和language组合起来才能把每一行区分开来。

    df.set_index(["data","language"], inplace=True)
    

    df 变为: image.png

    sort_index()

    在对多重索引进行切片之前,首先要对索引进行整理操作:

    df.sort_index(inplace=True)
    

    这时候df变为: image.png

此时可以通过给loc()传入一个元组来索引某个值:

df.loc[('2017-01-02','r')]

输出结果为:

ex_complete    8
Name: (2017-01-02, r), dtype: int64

reindex()

reindex()创建一个新的对象,它的数据顺序符合新的索引。可以实现通过标签选取数据的功能。DataFrame中,reindex可以修改(行)索引和列。只传递一个序列时,会重新索引结果的行。列可以用columns关键字重新索引。

DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill='')

重置DataFrame的索引,使用默认索引代替。当DataFrame有多层级索引时,该方法可以去掉一个或多个层级。 drop=False: 默认情况下,原先的索引会变成DataFrame的一列,如果drop=True则直接扔掉这一列。

reset_index()

重置DataFrame的index,使用默认的index。如果DataFrame是多重索引,该方法可以去掉一层或多层索引。 一个DataFrame Groupby 之后列索引会变成Groupby使用的那一列的特性,你可以使用reset_index()使它变成DataFrame的一列。

按照某一列或者两列排序

sort_values(by=列名, ascending=False)
sort_values(["breed", "weight_kg"],Ascending=False)

如何根据给定的列表来排序?

Grouping-Applying-Combining

Grouping-Applying的结果中,用于group的列会成为新的索引,如果使用的是两列,得到的是多重索引。 企业微信截图_479b10c8-996f-4301-ad9b-120b0bbc3589.png Groupby应该理解为分的过程而不是合。

image.png

Filter

将每个group看成一个DataFrame来筛选。

DateFrame的apply 和 agg区别

apply将函数应用于DataFrame,必须指定apply作用的轴, 0表示列(选取一列来操作)apply to all columns,1表示行(选取一行来操作)apply to all rows。apply()在大多数情况下都可以被agg()和transform()代替。

Groupby和resample联用

Note that, by combining grouping and resampling, you can answer a lot of questions about nearly any data set that includes time as a feature.

tranform()

Merge, join, concatenate and compare的区别

pandas提供了各种功能,可以轻松地将Series或DataFrame与各种索引的集合逻辑和连接/合并类操作的关系代数功能结合在一起。 image.png

高级合并功能一览表

企业微信截图_d0d27fd7-135c-4cb5-ab8c-70da28e8a698.png

merge

merge()用于根据共同列的值合并两个(或多个)dataframe(也可以使用索引,使用left_index=True或right_index=True) inner 方式的合并用于保存两份数据的交集。如果两列数据表示相同的含义,可以用left_on,right_on来指定这两列当作key。而不必重命名列名。 validate:检查merge的类型:

  • “one_to_one” or “1:1”: check if merge keys are unique in both left and right datasets.
  • “one_to_many” or “1:m”: check if merge keys are unique in left dataset.
  • “many_to_one” or “m:1”: check if merge keys are unique in right dataset.
  • “many_to_many” or “m:m”: allowed, but does not result in checks.

one to many merge 左边的表中的行如果与右边表中的多行有关可能会被复制很多次。

In [1]:
licenses.head()
Out[1]:
account ward  aid                   business               address    zip
0  307071    3  743       REGGIE'S BAR & GRILL       2105 S STATE ST  60616
1      10   10  829                 HONEYBEERS   13200 S HOUSTON AVE  60633
2   10002   14  775                CELINA DELI     5089 S ARCHER AVE  60632
3   10005   12  NaN  KRAFT FOODS NORTH AMERICA        2005 W 43RD ST  60609
4   10044   44  638  NEYBOUR'S TAVERN & GRILLE  3651 N SOUTHPORT AVE  60613
In [4]:
biz_owners.head()
Out[4]:

  account first_name  last_name      title
0      10      PEARL    SHERMAN  PRESIDENT
1      10      PEARL    SHERMAN  SECRETARY
2   10002     WALTER     MROZEK    PARTNER
3   10002     CELINA     BYRDAK    PARTNER
4   10005      IRENE  ROSENFELD  PRESIDENT

liscenses存储的是企业信息, biz_owners存储的是高管信息,一个公司可能有多个高管,所以高管信息的表中相同的account会重复出现。liscenses合并biz_owners的时候一个企业能够找到好几个高管,该企业所在的行就会重复很多次。

liscences_owners = liscences.merge(biz_owners,on="account")

concat

concat()用于将一个(或多个)dataframe追加到另一个下面(或横向,取决于轴选项是否设置为0或1)。 ingnore_index:是否忽略原先的index,重新索引 join:另外轴上的标题的处理,交集或者并集 sort:是否对另外的轴的列的位置进行排列 key:使用传入的key当作最外层的索引构建层次化索引

append(pandas 2.0之后已经淘汰了)

简化版的concat

merge_ordered()

适用于合并时间数据,可以设置填充缺失值的方法

merge_asof()

image.png

join()

join()用于在索引的基础上合并2个dataframe;我们可以使用join(),而不是使用带有left_index=True选项的merge()。

rename()

DataFrame.rename(mapper=None, index=None, columns=None, axis=None, copy=True, inplace=False, level=None, errors='ignore')

改变行标签或列标签,输入的字典或函数必须是一一对应的。字典中没有的标签将保持原样。提供多余的标签不会报错。

根据多个条件索引

image.png 为什么第一个表达式正常工作,第二个表达式会报错? https://stackoverflow.com/questions/21415661/logical-operators-for-boolean-indexing-in-pandas

a[(a['some_column']==some_number) & (a['some_other_column']==some_other_number)]
a[(a['some_column']==some_number) and (a['some_other_column']==some_other_number)]
(a['x']==1) and (a['y']==10)

当像上边的代码一样使用and的时候,隐式的要求pyhton将(a[‘x’]==1) and (a[‘y’]==10)转化为布尔值。Numpy的数组没有布尔值。当作布尔值使用的时候会抛出ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().的错误。

数据选择

image.png 选择行的时候iloc的速度要快于loc,选择列的时候[]比iloc快

https://colab.research.google.com/drive/1DyNXx4X0GFUcmVl4ykZ4L8j4CnCZOmKp#scrollTo=sTNHtQz3Mu_K

Recap:简要回顾

image.png

image.png

df[val]

索引某些列或者通过切片索引某些行,布尔型索引某些行

df[列名]

df[列名] 返回某一列数据组成的series

df['Artist']

企业微信截图_70105558-d9a6-4e1b-a7bd-4c55754b1213.png

df[[列名]]

df[[列名]]返回某一列数据和列标签组成的Dataframe

df[['Artist']]

企业微信截图_155f8114-b95b-411c-927a-b40b4a2e09b0.png

df[i:j]

df[i:j] 返回Dataframe的若干行(包前不包后)

df[1:3]

image.png

df.loc[]

df.loc[i]

返回某一行和列标签组成的series

df.loc[0]

image.png

df.loc[i:j]

返回若干行组成的Dataframe(包前又包后

df.loc[0:0]

image.png

df.iloc[]

链式索引导致SettingWithCopyWarning

这是一个很长的故事 https://realpython.com/pandas-settingwithcopywarning/

turb_df_AA = turb_df.iloc[9:18]
turb_df_AA["hdist_CP"] = get_hdist(x_CP, y_CP, turb_df_AA["x"], turb_df_AA["y"], direction)

SettingWithCopyWarning提示你,被修改的可能不是你想修改的DataFrame而是它的一个复制 df[mask]返回的是一个新的DataFrame。该DataFrame中存储的是df中满足条件的数据的复制。df[mask][“z”]将复制的DataFrame中的z赋值为0,df并未发生改变。

NumPy和Pandas中的视图和复制

可以通过df.copy(deep=False)获得视图,通过df.copy()获得复制 NumPy索引是获得视图还是复制取决于你所使用的索引的方法,包括slicing,integer indexing, Boolean indexing。 切片获得的是视图。 整数索引获得的是复制。 mask索引得到的是复制。 Keep in mind that these examples show how you can reference data in an array. Referencing data returns views when slicing arrays and copies when using index and mask arrays. Assignments, on the other hand, always modify the original data of the array. arr[1] = 64虽然是index索引也会改变数据的值 链式索引中视图和复制的表现则不相同。

时间处理

将日期和时间合并为一列

apple: image.png 将“/”替换为“-”

apple.date.str.replace("/", "-")

image.png 使用cat合并

apple.date.str.cat(apple.time, sep=" ")

combined image.png

将字符串转换为datetime对象

NO_data_obs["time"] = pd.to_datetime(NO_data_obs["time"])

通过to_datetime函数,可以把文本字符串转换为datetime(ie. datetime[ns,UTC])对象。在pandas中我们称这些datetime对象为pandas.Timestamp, 它类似于标准库中的datetime.datetime。 避免上述情况出现的方法是使用.loc[],.iloc[], .at[], .iat[]。

避免SettingWithCopyWarning 需要做好以下两点:

  • 避免链式赋值,比如df[“z”][mask]=0, df.loc[mask][“z”]=0
  • 使用单一赋值,只进行一次索引操作如df.loc[mask, “z”] = 0。

    通过正则表达式来过滤pandas的行

    使用pandas的contains功能

    遍历DataFrame

    使用iterrows(), 每次运行返回一个Pandas Series对象 例如:

    for lab, row in brics.iterrows() :
    

    lab返回这一行的行标签,row返回这一行的内容

    pivot table(透视表) & melt()

    数据透视表是一种技术,对数据进行重新排列或 “透视 “以总结某些信息。 Pivot tables are the standard way of aggregating data in spreadsheets. In pandas, pivot tables are essentially just another way of performing grouped calculations. 数据透视表是把明细表进行分类汇总的过程。

    pandas.pivot_table(values,index,columns)
    

    values:将要分类汇总的数据。 index:透视表中的行。 columns:透视表中的列。 image.png pivot_table 和melt实现的是Wide Format和Long Format之间的转换。Wide Format更适合人类阅读,Long Format更适合机器阅读。 Long Format中只value放在一列, 其它的是标签, Wide Format的columns变成Long Format的标签。 企业微信截图_9ea9946e-c45e-46f7-bdb6-6f54b9f0a968.png

迭代pandas的每行

获取DataFrame的行数

三种方法可以实现:

len(df.index)
df.shape[0]
df[df.columns[0]].count() #non-NaN values of first column

速度对比如下: image.png

数据清洗

检查缺失数据

pd.isna.sum()

缺失的数据可以用中位数代替。 将pandas两列数据合并为1列 str.cat

df.duplicated(subset, keep)

返回表示重复行的布尔Series subset:考虑哪些列检查是否有重复值,默认考虑所有列 keep:标记哪一个重复值为True

  • first 除了第一个出现的值外标记为True
  • last 除了最后一个出现的值外标记为True
  • False 所有的值都标记为True

    unique()

    以数组的形式返回某一列的唯一值,如果要返回列表可以用tolist()

    drop_duplicates(subset, keep,inplace)

    作用于pandas的某一列,返回去除重复值的Pandas series。

可以用nunique()或者len()统计唯一值的个数。 企业微信截图_6cc67848-f0fd-412a-aae7-363d243613d4.png

replace()替换某些值

value_counts()统计某列每个值出现的频率

加了normalize=True之后显示的是每个分类所占的比例 企业微信截图_27b6f389-bf74-4ee8-8ec2-8666f2270176.png

str.功能

str.contains(,na=False)

str.replace()

str.cat()

Resample

按年“A”, 按月“M”

pd.crosstab计算频率表

pandas.cut

将数值数据切分为类型数据

Categorical数据

使用分类变量的好处

可以节省内存 object类型占用的存储空间是category类型的7.5倍。