乐趣区

关于程序员:Pandas-数据类型概述

在进行数据分析时,确保应用正确的数据类型是很重要的,否则完满可能会失去意想不到的后果或甚至是谬误后果。对于 pandas 来说,它会在许多状况下正确的推断出数据类型

只管 pandas 曾经自我推断的很好了,但在咱们的数据分析过程中,可能依然须要显式地将数据从一种类型转换为另一种类型。本文将探讨根本的 pandas 数据类型(又名 dtypes),它们如何映射到 python 和 numpy 数据类型,以及从一种 pandas 类型转换为另一种的办法

Pandas 数据类型

数据类型实质上是编程语言用来了解如何存储和操作数据的内部结构。例如,一个程序须要了解将两个数字相加,如 5 + 10 失去 15。或者有两个字符串,如“cat”和“hat”,能够将它们连贯(加)在一起失去“cathat”

对于 pandas 数据类型的一个可能令人困惑的中央是 pandas、python 和 numpy 之间存在一些出入

下表做了相干的总结

Pandas dtype Python type NumPy type Usage
object str or mixed string_, unicode_, mixed types Text or mixed numeric and non-numeric values
int64 int int_, int8, int16, int32, int64, uint8, uint16, uint32, uint64 Integer numbers
float64 float float_, float16, float32, float64 Floating point numbers
bool bool bool_ True/False values
datetime64 NA datetime64[ns] Date and time values
timedelta[ns] NA NA Differences between two datetimes
category NA NA Finite list of text values

不过在大多数状况下,无需放心是否应该尝试显式地将 pandas 类型强制为对应于 NumPy 类型。大多数时候,应用 pandas 默认的 int64 和 float64 类型就能够了

上面咱们将重点介绍以下 pandas 类型:

  • object
  • int64
  • float64
  • datetime64
  • bool

而对于 category 和 timedelta 类型,咱们会在前面的文章中重点介绍

还须要留神的是 object 数据类型实际上能够蕴含多种不同的类型。例如,a 列能够包含整数、浮点数和字符串,它们统称为 object。因而,咱们可能须要一些额定的技术来解决object 列中的混合数据类型,咱们也在前面的文章专门探讨

上面咱们先来查看本文应用的测试数据

import numpy as np
import pandas as pd

df = pd.read_csv("sales_data_types.csv")

Output:

乍一看,数据如同还不错,所以咱们能够尝试做一些操作来剖析数据。让咱们尝试将 2016 年和 2017 年的销售额相加:

df['2016'] + df['2017']

Output:

0      $125,000.00$162500.00
1    $920,000.00$101,2000.00
2        $50,000.00$62500.00
3      $350,000.00$490000.00
4        $15,000.00$12750.00
dtype: object

后果显然不是咱们冀望的,咱们心愿将总数加在一起,但 pandas 只是将两个值连贯在一起。其实问题也很显著,咱们的数据类型是dtype: object,object 是 pandas 中的字符串,因而它执行字符串操作而不是数学操作

咱们能够通过如下代码查看数据所有的数据类型信息

df.dtypes

Output:

Customer Number    float64
Customer Name       object
2016                object
2017                object
Percent Growth      object
Jan Units           object
Month                int64
Day                  int64
Year                 int64
Active              object
dtype: object

当然咱们还能够应用 df.info() 来查看更多信息

df.info()

Output:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 10 columns):
 #   Column           Non-Null Count  Dtype  
---  ------           --------------  -----  
 0   Customer Number  5 non-null      float64
 1   Customer Name    5 non-null      object 
 2   2016             5 non-null      object 
 3   2017             5 non-null      object 
 4   Percent Growth   5 non-null      object 
 5   Jan Units        5 non-null      object 
 6   Month            5 non-null      int64  
 7   Day              5 non-null      int64  
 8   Year             5 non-null      int64  
 9   Active           5 non-null      object 
dtypes: float64(1), int64(3), object(6)
memory usage: 528.0+ bytes

以上都是 Pandas 为咱们主动调配的数据类型,有几个问题:

  • Customer Number 是 float64 但应该是 int64
  • 2016 和 2017 列存储为 object,而不是诸如 float64 或 int64 之类的数值
  • 百分比增长和一月单位也存储为 object 而不是数值
  • 列 Month、Day 和 Year 应转换为 datetime64 类型
  • Active 列应该是一个布尔值

也就是说,在咱们进行数据分析之前,咱们必须手动更正这些数据类型

在 pandas 中转换数据类型,有三个根本选项:

  • 应用 astype() 强制转换数据类型
  • 创立自定义函数来转换数据
  • 应用 pandas 函数,例如 to_numeric() 或 to_datetime()

应用 astype() 函数

将 pandas 数据列转换为不同类型的最简略办法是应用 astype(),例如,要将 Customer Number 转换为整数,咱们能够这样调用它:

df['Customer Number'].astype('int')

Output:

0     10002
1    552278
2     23477
3     24900
4    651029
Name: Customer Number, dtype: int32

如果咱们想更改原始数据中的信息,则须要定义变量接管返回值,因为 astype() 函数返回一个正本

df["Customer Number"] = df['Customer Number'].astype('int')
df.dtypes

Output:

Customer Number     int32
Customer Name      object
2016               object
2017               object
Percent Growth     object
Jan Units          object
Month               int64
Day                 int64
Year                int64
Active             object
dtype: object

这样咱们就实现了 Customer Number 列的类型转换

看起来很简略,让咱们尝试对 2016 列做同样的事件,并将其转换为浮点数:

同样的,转换 Jan Units 列

转换异样了

下面的状况,数据中蕴含了无奈转换为数字的值。在 sales 列中,数据包含货币符号以及每个值中的逗号。在 Jan Units 列中,最初一个值是“Closed”,它不是数字

咱们再来尝试转换 Active 列

df['Active'].astype('bool')

Output:

0    True
1    True
2    True
3    True
4    True
Name: Active, dtype: bool

乍一看仿佛还不错,但仔细观察,问题就大了。所有值都被解释为 True,但最初一位客户的 Active 标记为 N,居然也被转换为 True 了

所以,咱们能够失去,astype() 的应用是有条件的,仅在以下状况下才无效:

  • 数据是洁净的,能够简略地转换为一个数字
  • 将数值转换为字符串对象

如果数据有非数字字符或者不是同质的,那么 astype() 将不是类型转换的好抉择。咱们须要进行额定的转换能力使类型更改失常工作

自定义转换函数

因为此数据的转换有点简单,咱们能够构建一个自定义函数,将其利用于每个值并转换为适当的数据类型

对于(这个特定数据集的)货币转换,咱们能够应用一个简略的函数:

def convert_currency(val):
    """
    Convert the string number value to a float
     - Remove $
     - Remove commas
     - Convert to float type
    """new_val = val.replace(',','').replace('$', '')
    return float(new_val)

该代码应用 python 的字符串函数去除“$”和“,”,而后将值转换为浮点数

也行有人会倡议咱们应用 Decimal 类型的货币。但这不是 pandas 中的内置数据类型,所以咱们应用 float 办法

当初咱们能够应用 pandas 的 apply 函数将其利用于 2016 列中的所有值

df['2016'].apply(convert_currency)

Output:

0    125000.0
1    920000.0
2     50000.0
3    350000.0
4     15000.0
Name: 2016, dtype: float64

胜利了!

当然咱们也能够应用 lambda 函数来解决,代码简洁了,然而可读性却降落了

df['2016'].apply(lambda x: x.replace('$', '').replace(',','')).astype('float')

接下来解决 Active 列,自定义函数须要应用 np.where()。有几种可能的办法能够解决这个特定问题。np.where() 办法对许多类型的问题都很有用,所以咱们抉择在这里应用

根本思维是应用 np.where() 函数将所有“Y”值转换为 True 并将其余所有值转换为 False

df["Active"] = np.where(df["Active"] == "Y", True, False)

Output:

数据类型也转换为 bool 了

df.dtypes

Output:

Customer Number     int32
Customer Name      object
2016               object
2017               object
Percent Growth     object
Jan Units          object
Month               int64
Day                 int64
Year                int64
Active               bool
dtype: object

Pandas 辅助函数

Pandas 在 astype() 函数和更简单的自定义函数之间有一个两头地带,这些辅助函数对于某些数据类型转换十分有用

到目前为止,咱们没有对日期列或 Jan Units 列做任何事件。这两者都能够简略地应用内置的 pandas 函数进行转换,例如 pd.to_numeric() 和 pd.to_datetime()

Jan Units 转换存在问题的起因是列中蕴含非数字值。如果咱们尝试应用 astype() 咱们会失去一个谬误(如前所述)。pd.to_numeric() 函数能够更优雅地解决这些值:

pd.to_numeric(df['Jan Units'], errors='coerce')

Output:

0    500.0
1    700.0
2    125.0
3     75.0
4      NaN
Name: Jan Units, dtype: float64

有几点须要留神。首先,该函数能够轻松解决数据并创立一个 float64 列。此外,它用 NaN 值替换了有效的“Closed”值,因为咱们传递了 errors=coerce。咱们能够保留该值或应用 fillna(0) 将其填充为 0:

pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)

Output:

0    500.0
1    700.0
2    125.0
3     75.0
4      0.0
Name: Jan Units, dtype: float64

最初咱们应用 pd.to_datetime() 函数来解决日期数据

pd.to_datetime(df[['Month', 'Day', 'Year']])

Output:

0   2015-01-10
1   2014-06-15
2   2016-03-29
3   2015-10-27
4   2014-02-02
dtype: datetime64[ns]

该函数将列组合成一系列适当的 datateime64 dtype,很不便

最初,咱们把下面解决代码都放到一起

df_2 = pd.read_csv("sales_data_types.csv",
                   dtype={'Customer Number': 'int'},
                   converters={'2016': convert_currency,
                               '2017': convert_currency,
                               'Percent Growth': convert_percent,
                               'Jan Units': lambda x: pd.to_numeric(x, errors='coerce'),
                               'Active': lambda x: np.where(x == "Y", True, False)
                              })

df_2.dtypes

Output:

Customer Number      int32
Customer Name       object
2016               float64
2017               float64
Percent Growth     float64
Jan Units          float64
Month                int64
Day                  int64
Year                 int64
Active              object
dtype: object

好了,这就是明天分享的全部内容,喜爱就点个赞 + 在看吧~

本文由 mdnice 多平台公布

退出移动版