Python 数据分析(PYDA)第三版(五)(2)

简介: Python 数据分析(PYDA)第三版(五)

Python 数据分析(PYDA)第三版(五)(1)https://developer.aliyun.com/article/1482387


示例:随机抽样和排列

假设您想要从大型数据集中随机抽取(有或没有替换)用于蒙特卡洛模拟或其他应用。有许多执行“抽取”的方法;在这里,我们使用 Series 的sample方法。

为了演示,这里有一种构建一副英式扑克牌的方法:

suits = ["H", "S", "C", "D"]  # Hearts, Spades, Clubs, Diamonds
card_val = (list(range(1, 11)) + [10] * 3) * 4
base_names = ["A"] + list(range(2, 11)) + ["J", "K", "Q"]
cards = []
for suit in suits:
 cards.extend(str(num) + suit for num in base_names)
deck = pd.Series(card_val, index=cards)

现在我们有一个长度为 52 的 Series,其索引包含牌名,值是在二十一点和其他游戏中使用的值(为了简单起见,我让 ace "A"为 1):

In [122]: deck.head(13)
Out[122]: 
AH      1
2H      2
3H      3
4H      4
5H      5
6H      6
7H      7
8H      8
9H      9
10H    10
JH     10
KH     10
QH     10
dtype: int64

现在,根据我之前说的,从牌组中抽取五张牌可以写成:

In [123]: def draw(deck, n=5):
 .....:     return deck.sample(n)
In [124]: draw(deck)
Out[124]: 
4D     4
QH    10
8S     8
7D     7
9C     9
dtype: int64

假设你想要从每种花色中抽取两张随机牌。因为花色是每张牌名称的最后一个字符,我们可以根据这个进行分组,并使用apply

In [125]: def get_suit(card):
 .....:     # last letter is suit
 .....:     return card[-1]
In [126]: deck.groupby(get_suit).apply(draw, n=2)
Out[126]: 
C  6C     6
 KC    10
D  7D     7
 3D     3
H  7H     7
 9H     9
S  2S     2
 QS    10
dtype: int64

或者,我们可以传递group_keys=False以删除外部套索索引,只留下所选的卡:

In [127]: deck.groupby(get_suit, group_keys=False).apply(draw, n=2)
Out[127]: 
AC      1
3C      3
5D      5
4D      4
10H    10
7H      7
QS     10
7S      7
dtype: int64

示例:组加权平均和相关性

groupby的分割-应用-组合范式下,DataFrame 或两个 Series 中的列之间的操作,例如组加权平均,是可能的。例如,考虑包含组键、值和一些权重的数据集:

In [128]: df = pd.DataFrame({"category": ["a", "a", "a", "a",
 .....:                                 "b", "b", "b", "b"],
 .....:                    "data": np.random.standard_normal(8),
 .....:                    "weights": np.random.uniform(size=8)})
In [129]: df
Out[129]: 
 category      data   weights
0        a -1.691656  0.955905
1        a  0.511622  0.012745
2        a -0.401675  0.137009
3        a  0.968578  0.763037
4        b -1.818215  0.492472
5        b  0.279963  0.832908
6        b -0.200819  0.658331
7        b -0.217221  0.612009

category加权平均值将是:

In [130]: grouped = df.groupby("category")
In [131]: def get_wavg(group):
 .....:     return np.average(group["data"], weights=group["weights"])
In [132]: grouped.apply(get_wavg)
Out[132]: 
category
a   -0.495807
b   -0.357273
dtype: float64

另一个例子是,考虑一个最初从 Yahoo! Finance 获取的金融数据集,其中包含一些股票的日终价格和标准普尔 500 指数(SPX符号):

In [133]: close_px = pd.read_csv("examples/stock_px.csv", parse_dates=True,
 .....:                        index_col=0)
In [134]: close_px.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 2214 entries, 2003-01-02 to 2011-10-14
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   AAPL    2214 non-null   float64
 1   MSFT    2214 non-null   float64
 2   XOM     2214 non-null   float64
 3   SPX     2214 non-null   float64
dtypes: float64(4)
memory usage: 86.5 KB
In [135]: close_px.tail(4)
Out[135]: 
 AAPL   MSFT    XOM      SPX
2011-10-11  400.29  27.00  76.27  1195.54
2011-10-12  402.19  26.96  77.16  1207.25
2011-10-13  408.43  27.18  76.37  1203.66
2011-10-14  422.00  27.27  78.11  1224.58

这里的 DataFrame info()方法是获取 DataFrame 内容概述的便捷方式。

一个感兴趣的任务可能是计算一个由每日收益(从百分比变化计算)与SPX的年度相关性组成的 DataFrame。作为一种方法,我们首先创建一个函数,计算每列与"SPX"列的成对相关性:

In [136]: def spx_corr(group):
 .....:     return group.corrwith(group["SPX"])

接下来,我们使用pct_change计算close_px的百分比变化:

In [137]: rets = close_px.pct_change().dropna()

最后,我们按年将这些百分比变化分组,可以使用一个一行函数从每个行标签中提取datetime标签的year属性:

In [138]: def get_year(x):
 .....:     return x.year
In [139]: by_year = rets.groupby(get_year)
In [140]: by_year.apply(spx_corr)
Out[140]: 
 AAPL      MSFT       XOM  SPX
2003  0.541124  0.745174  0.661265  1.0
2004  0.374283  0.588531  0.557742  1.0
2005  0.467540  0.562374  0.631010  1.0
2006  0.428267  0.406126  0.518514  1.0
2007  0.508118  0.658770  0.786264  1.0
2008  0.681434  0.804626  0.828303  1.0
2009  0.707103  0.654902  0.797921  1.0
2010  0.710105  0.730118  0.839057  1.0
2011  0.691931  0.800996  0.859975  1.0

您还可以计算列间的相关性。这里我们计算苹果和微软之间的年度相关性:

In [141]: def corr_aapl_msft(group):
 .....:     return group["AAPL"].corr(group["MSFT"])
In [142]: by_year.apply(corr_aapl_msft)
Out[142]: 
2003    0.480868
2004    0.259024
2005    0.300093
2006    0.161735
2007    0.417738
2008    0.611901
2009    0.432738
2010    0.571946
2011    0.581987
dtype: float64

示例:组内线性回归

与前面的示例相同,您可以使用groupby执行更复杂的组内统计分析,只要函数返回一个 pandas 对象或标量值。例如,我可以定义以下regress函数(使用statsmodels计量经济学库),它在每个数据块上执行普通最小二乘(OLS)回归:

import statsmodels.api as sm
def regress(data, yvar=None, xvars=None):
 Y = data[yvar]
 X = data[xvars]
 X["intercept"] = 1.
 result = sm.OLS(Y, X).fit()
 return result.params

如果您尚未安装statsmodels,可以使用 conda 安装它:

conda install statsmodels

现在,要在AAPLSPX回报的年度线性回归中执行:

In [144]: by_year.apply(regress, yvar="AAPL", xvars=["SPX"])
Out[144]: 
 SPX  intercept
2003  1.195406   0.000710
2004  1.363463   0.004201
2005  1.766415   0.003246
2006  1.645496   0.000080
2007  1.198761   0.003438
2008  0.968016  -0.001110
2009  0.879103   0.002954
2010  1.052608   0.001261
2011  0.806605   0.001514

10.4 组转换和“展开”的 GroupBys

在 Apply: General split-apply-combine 中,我们看了一下在分组操作中执行转换的apply方法。还有另一个内置方法叫做transform,它类似于apply,但对您可以使用的函数种类施加了更多的约束:

  • 它可以生成一个标量值广播到组的形状。
  • 它可以生成与输入组相同形状的对象。
  • 它不能改变其输入。

让我们考虑一个简单的例子以说明:

In [145]: df = pd.DataFrame({'key': ['a', 'b', 'c'] * 4,
 .....:                    'value': np.arange(12.)})
In [146]: df
Out[146]: 
 key  value
0    a    0.0
1    b    1.0
2    c    2.0
3    a    3.0
4    b    4.0
5    c    5.0
6    a    6.0
7    b    7.0
8    c    8.0
9    a    9.0
10   b   10.0
11   c   11.0

这里是按键的组平均值:

In [147]: g = df.groupby('key')['value']
In [148]: g.mean()
Out[148]: 
key
a    4.5
b    5.5
c    6.5
Name: value, dtype: float64

假设我们想要生成一个与df['value']相同形状的 Series,但值被按'key'分组后的平均值替换。我们可以传递一个计算单个组平均值的函数给transform

In [149]: def get_mean(group):
 .....:     return group.mean()
In [150]: g.transform(get_mean)
Out[150]: 
0     4.5
1     5.5
2     6.5
3     4.5
4     5.5
5     6.5
6     4.5
7     5.5
8     6.5
9     4.5
10    5.5
11    6.5
Name: value, dtype: float64

对于内置的聚合函数,我们可以像 GroupBy agg方法一样传递一个字符串别名:

In [151]: g.transform('mean')
Out[151]: 
0     4.5
1     5.5
2     6.5
3     4.5
4     5.5
5     6.5
6     4.5
7     5.5
8     6.5
9     4.5
10    5.5
11    6.5
Name: value, dtype: float64

apply一样,transform适用于返回 Series 的函数,但结果必须与输入的大小相同。例如,我们可以使用一个辅助函数将每个组乘以 2:

In [152]: def times_two(group):
 .....:     return group * 2
In [153]: g.transform(times_two)
Out[153]: 
0      0.0
1      2.0
2      4.0
3      6.0
4      8.0
5     10.0
6     12.0
7     14.0
8     16.0
9     18.0
10    20.0
11    22.0
Name: value, dtype: float64

作为一个更复杂的例子,我们可以计算每个组按降序排名:

In [154]: def get_ranks(group):
 .....:     return group.rank(ascending=False)
In [155]: g.transform(get_ranks)
Out[155]: 
0     4.0
1     4.0
2     4.0
3     3.0
4     3.0
5     3.0
6     2.0
7     2.0
8     2.0
9     1.0
10    1.0
11    1.0
Name: value, dtype: float64

考虑一个由简单聚合组成的组转换函数:

In [156]: def normalize(x):
 .....:     return (x - x.mean()) / x.std()

在这种情况下,我们可以使用transformapply获得等效的结果:

In [157]: g.transform(normalize)
Out[157]: 
0    -1.161895
1    -1.161895
2    -1.161895
3    -0.387298
4    -0.387298
5    -0.387298
6     0.387298
7     0.387298
8     0.387298
9     1.161895
10    1.161895
11    1.161895
Name: value, dtype: float64
In [158]: g.apply(normalize)
Out[158]: 
key 
a    0    -1.161895
 3    -0.387298
 6     0.387298
 9     1.161895
b    1    -1.161895
 4    -0.387298
 7     0.387298
 10    1.161895
c    2    -1.161895
 5    -0.387298
 8     0.387298
 11    1.161895
Name: value, dtype: float64

内置的聚合函数如'mean''sum'通常比一般的apply函数快得多。当与transform一起使用时,这些函数也有一个“快速路径”。这使我们能够执行所谓的展开组操作:

In [159]: g.transform('mean')
Out[159]: 
0     4.5
1     5.5
2     6.5
3     4.5
4     5.5
5     6.5
6     4.5
7     5.5
8     6.5
9     4.5
10    5.5
11    6.5
Name: value, dtype: float64
In [160]: normalized = (df['value'] - g.transform('mean')) / g.transform('std')
In [161]: normalized
Out[161]: 
0    -1.161895
1    -1.161895
2    -1.161895
3    -0.387298
4    -0.387298
5    -0.387298
6     0.387298
7     0.387298
8     0.387298
9     1.161895
10    1.161895
11    1.161895
Name: value, dtype: float64

在这里,我们在多个 GroupBy 操作的输出之间进行算术运算,而不是编写一个函数并将其传递给groupby(...).apply。这就是所谓的“展开”。

尽管展开的组操作可能涉及多个组聚合,但矢量化操作的整体效益通常超过了这一点。

10.5 透视表和交叉制表

透视表是一种经常在电子表格程序和其他数据分析软件中找到的数据汇总工具。它通过一个或多个键对数据表进行聚合,将数据排列在一个矩形中,其中一些组键沿行排列,另一些沿列排列。在 Python 中,通过本章描述的groupby功能以及利用分层索引进行重塑操作,可以实现使用 pandas 的透视表。DataFrame 还有一个pivot_table方法,还有一个顶级的pandas.pivot_table函数。除了提供一个方便的groupby接口外,pivot_table还可以添加部分总计,也称为边际

返回到小费数据集,假设您想要计算按daysmoker排列的组平均值的表格(默认的pivot_table聚合类型):

In [162]: tips.head()
Out[162]: 
 total_bill   tip smoker  day    time  size   tip_pct
0       16.99  1.01     No  Sun  Dinner     2  0.059447
1       10.34  1.66     No  Sun  Dinner     3  0.160542
2       21.01  3.50     No  Sun  Dinner     3  0.166587
3       23.68  3.31     No  Sun  Dinner     2  0.139780
4       24.59  3.61     No  Sun  Dinner     4  0.146808
In [163]: tips.pivot_table(index=["day", "smoker"],
 .....:                  values=["size", "tip", "tip_pct", "total_bill"])
Out[163]: 
 size       tip   tip_pct  total_bill
day  smoker 
Fri  No      2.250000  2.812500  0.151650   18.420000
 Yes     2.066667  2.714000  0.174783   16.813333
Sat  No      2.555556  3.102889  0.158048   19.661778
 Yes     2.476190  2.875476  0.147906   21.276667
Sun  No      2.929825  3.167895  0.160113   20.506667
 Yes     2.578947  3.516842  0.187250   24.120000
Thur No      2.488889  2.673778  0.160298   17.113111
 Yes     2.352941  3.030000  0.163863   19.190588

这可以直接使用groupby生成,使用tips.groupby(["day", "smoker"]).mean()。现在,假设我们只想计算tip_pctsize的平均值,并另外按time分组。我将smoker放在表格列中,timeday放在行中:

In [164]: tips.pivot_table(index=["time", "day"], columns="smoker",
 .....:                  values=["tip_pct", "size"])
Out[164]: 
 size             tip_pct 
smoker             No       Yes        No       Yes
time   day 
Dinner Fri   2.000000  2.222222  0.139622  0.165347
 Sat   2.555556  2.476190  0.158048  0.147906
 Sun   2.929825  2.578947  0.160113  0.187250
 Thur  2.000000       NaN  0.159744       NaN
Lunch  Fri   3.000000  1.833333  0.187735  0.188937
 Thur  2.500000  2.352941  0.160311  0.163863

我们可以通过传递margins=True来增加此表,以包括部分总计。这将添加All行和列标签,相应的值是单个层次内所有数据的组统计信息:

In [165]: tips.pivot_table(index=["time", "day"], columns="smoker",
 .....:                  values=["tip_pct", "size"], margins=True)
Out[165]: 
 size                       tip_pct 
smoker             No       Yes       All        No       Yes       All
time   day 
Dinner Fri   2.000000  2.222222  2.166667  0.139622  0.165347  0.158916
 Sat   2.555556  2.476190  2.517241  0.158048  0.147906  0.153152
 Sun   2.929825  2.578947  2.842105  0.160113  0.187250  0.166897
 Thur  2.000000       NaN  2.000000  0.159744       NaN  0.159744
Lunch  Fri   3.000000  1.833333  2.000000  0.187735  0.188937  0.188765
 Thur  2.500000  2.352941  2.459016  0.160311  0.163863  0.161301
All          2.668874  2.408602  2.569672  0.159328  0.163196  0.160803

这里,All值是没有考虑吸烟者与非吸烟者(All列)或行中的两个级别分组的平均值(All行)。

要使用除mean之外的聚合函数,请将其传递给aggfunc关键字参数。例如,"count"len将为您提供组大小的交叉制表(计数或频率)(尽管"count"将在数据组内排除空值的计数,而len不会):

In [166]: tips.pivot_table(index=["time", "smoker"], columns="day",
 .....:                  values="tip_pct", aggfunc=len, margins=True)
Out[166]: 
day             Fri   Sat   Sun  Thur  All
time   smoker 
Dinner No       3.0  45.0  57.0   1.0  106
 Yes      9.0  42.0  19.0   NaN   70
Lunch  No       1.0   NaN   NaN  44.0   45
 Yes      6.0   NaN   NaN  17.0   23
All            19.0  87.0  76.0  62.0  244

如果某些组合为空(或其他 NA),您可能希望传递一个fill_value

In [167]: tips.pivot_table(index=["time", "size", "smoker"], columns="day",
 .....:                  values="tip_pct", fill_value=0)
Out[167]: 
day                      Fri       Sat       Sun      Thur
time   size smoker 
Dinner 1    No      0.000000  0.137931  0.000000  0.000000
 Yes     0.000000  0.325733  0.000000  0.000000
 2    No      0.139622  0.162705  0.168859  0.159744
 Yes     0.171297  0.148668  0.207893  0.000000
 3    No      0.000000  0.154661  0.152663  0.000000
...                      ...       ...       ...       ...
Lunch  3    Yes     0.000000  0.000000  0.000000  0.204952
 4    No      0.000000  0.000000  0.000000  0.138919
 Yes     0.000000  0.000000  0.000000  0.155410
 5    No      0.000000  0.000000  0.000000  0.121389
 6    No      0.000000  0.000000  0.000000  0.173706
[21 rows x 4 columns]

请参阅表 10.2 以获取pivot_table选项的摘要。

表 10.2:pivot_table选项

参数 描述
values 要聚合的列名;默认情况下,聚合所有数值列
index 要在生成的透视表的行上分组的列名或其他组键
columns 要在生成的透视表的列上分组的列名或其他组键
aggfunc 聚合函数或函数列表(默认为"mean");可以是在groupby上下文中有效的任何函数
fill_value 替换结果表中的缺失值
dropna 如果为True,则不包括所有条目都为NA的列
margins 添加行/列小计和总计(默认为False
margins_name 在传递margins=True时用于边缘行/列标签的名称;默认为"All"
observed 使用分类组键,如果为True,则仅显示键中的观察类别值,而不是所有类别

交叉制表:交叉制表

交叉制表(或简称为交叉制表)是计算组频率的透视表的一种特殊情况。这里是一个例子:

In [168]: from io import StringIO
In [169]: data = """Sample  Nationality  Handedness
 .....: 1   USA  Right-handed
 .....: 2   Japan    Left-handed
 .....: 3   USA  Right-handed
 .....: 4   Japan    Right-handed
 .....: 5   Japan    Left-handed
 .....: 6   Japan    Right-handed
 .....: 7   USA  Right-handed
 .....: 8   USA  Left-handed
 .....: 9   Japan    Right-handed
 .....: 10  USA  Right-handed"""
 .....:
In [170]: data = pd.read_table(StringIO(data), sep="\s+")
In [171]: data
Out[171]: 
 Sample Nationality    Handedness
0       1         USA  Right-handed
1       2       Japan   Left-handed
2       3         USA  Right-handed
3       4       Japan  Right-handed
4       5       Japan   Left-handed
5       6       Japan  Right-handed
6       7         USA  Right-handed
7       8         USA   Left-handed
8       9       Japan  Right-handed
9      10         USA  Right-handed

作为一些调查分析的一部分,我们可能希望按国籍和惯用手总结这些数据。您可以使用pivot_table来做到这一点,但pandas.crosstab函数可能更方便:

In [172]: pd.crosstab(data["Nationality"], data["Handedness"], margins=True)
Out[172]: 
Handedness   Left-handed  Right-handed  All
Nationality 
Japan                  2             3    5
USA                    1             4    5
All                    3             7   10

crosstab的前两个参数可以是数组、Series 或数组列表。就像在小费数据中一样:

In [173]: pd.crosstab([tips["time"], tips["day"]], tips["smoker"], margins=True)
Out[173]: 
smoker        No  Yes  All
time   day 
Dinner Fri     3    9   12
 Sat    45   42   87
 Sun    57   19   76
 Thur    1    0    1
Lunch  Fri     1    6    7
 Thur   44   17   61
All          151   93  244

10.6 结论

掌握 pandas 的数据分组工具可以帮助数据清洗和建模或统计分析工作。在 Ch 13:数据分析示例中,我们将查看几个更多实际数据上使用groupby的示例用例。

在下一章中,我们将把注意力转向时间序列数据。

十一、时间序列

原文:wesmckinney.com/book/time-series

译者:飞龙

协议:CC BY-NC-SA 4.0

此开放访问网络版本的《Python 数据分析第三版》现已作为印刷版和数字版的伴侣提供。如果您发现任何勘误,请在此处报告。请注意,由 Quarto 生成的本站点的某些方面与 O’Reilly 的印刷版和电子书版本的格式不同。

如果您发现本书的在线版本有用,请考虑订购纸质版无 DRM 的电子书以支持作者。本网站的内容不得复制或再生产。代码示例采用 MIT 许可,可在 GitHub 或 Gitee 上找到。

时间序列数据是许多不同领域中的结构化数据的重要形式,如金融、经济、生态学、神经科学和物理学。任何在许多时间点重复记录的东西都构成一个时间序列。许多时间序列是固定频率的,也就是说,数据点按照某种规则定期发生,例如每 15 秒、每 5 分钟或每月一次。时间序列也可以是不规则的,没有固定的时间单位或单位之间的偏移。如何标记和引用时间序列数据取决于应用程序,您可能有以下之一:

时间戳

特定的时间点。

固定周期

例如 2017 年 1 月的整个月,或 2020 年的整年。

时间间隔

由开始和结束时间戳指示。周期可以被视为间隔的特殊情况。

实验或经过的时间

每个时间戳都是相对于特定开始时间的时间度量(例如,自放入烤箱以来每秒烘烤的饼干的直径),从 0 开始。

在本章中,我主要关注前三类时间序列,尽管许多技术也可以应用于实验时间序列,其中索引可能是整数或浮点数,表示从实验开始经过的时间。最简单的时间序列是由时间戳索引的。

提示:

pandas 还支持基于时间差的索引,这是一种表示实验或经过时间的有用方式。我们在本书中没有探讨时间差索引,但您可以在pandas 文档中了解更多。

pandas 提供了许多内置的时间序列工具和算法。您可以高效地处理大型时间序列,对不规则和固定频率的时间序列进行切片、聚合和重采样。其中一些工具对金融和经济应用很有用,但您当然也可以用它们来分析服务器日志数据。

与其他章节一样,我们首先导入 NumPy 和 pandas:

In [12]: import numpy as np
In [13]: import pandas as pd

11.1 日期和时间数据类型和工具

Python 标准库包括用于日期和时间数据以及与日历相关的功能的数据类型。datetimetimecalendar模块是主要的起点。datetime.datetime类型,或简称datetime,被广泛使用:

In [14]: from datetime import datetime
In [15]: now = datetime.now()
In [16]: now
Out[16]: datetime.datetime(2023, 4, 12, 13, 9, 16, 484533)
In [17]: now.year, now.month, now.day
Out[17]: (2023, 4, 12)

datetime 存储日期和时间,精确到微秒。datetime.timedelta,或简称timedelta,表示两个datetime对象之间的时间差:

In [18]: delta = datetime(2011, 1, 7) - datetime(2008, 6, 24, 8, 15)
In [19]: delta
Out[19]: datetime.timedelta(days=926, seconds=56700)
In [20]: delta.days
Out[20]: 926
In [21]: delta.seconds
Out[21]: 56700

您可以将timedelta或其倍数添加(或减去)到datetime对象中,以产生一个新的偏移对象:

In [22]: from datetime import timedelta
In [23]: start = datetime(2011, 1, 7)
In [24]: start + timedelta(12)
Out[24]: datetime.datetime(2011, 1, 19, 0, 0)
In [25]: start - 2 * timedelta(12)
Out[25]: datetime.datetime(2010, 12, 14, 0, 0)

表 11.1 总结了datetime模块中的数据类型。虽然本章主要关注 pandas 中的数据类型和高级时间序列操作,但您可能会在 Python 的许多其他地方遇到基于datetime的类型。

表 11.1:datetime模块中的类型

类型 描述
date 使用公历存储日期(年,月,日)
time 以小时,分钟,秒和微秒存储一天中的时间
datetime 存储日期和时间
timedelta 两个datetime值之间的差异(以天,秒和微秒计)
tzinfo 存储时区信息的基本类型

在字符串和日期时间之间转换

您可以使用strstrftime方法对datetime对象和 pandas 的Timestamp对象进行格式化为字符串,传递格式规范:

In [26]: stamp = datetime(2011, 1, 3)
In [27]: str(stamp)
Out[27]: '2011-01-03 00:00:00'
In [28]: stamp.strftime("%Y-%m-%d")
Out[28]: '2011-01-03'

请参阅表 11.2 以获取完整的格式代码列表。

表 11.2:datetime格式规范(ISO C89 兼容)

类型 描述
%Y 四位数年份
%y 两位数年份
%m 两位数月份[01, 12]
%d 两位数日期[01, 31]
%H 小时(24 小时制)[00, 23]
%I 小时(12 小时制)[01, 12]
%M 两位数分钟[00, 59]
%S 秒[00, 61](秒 60, 61 表示闰秒)
%f 微秒作为整数,零填充(从 000000 到 999999)
%j 一年中的日期作为零填充的整数(从 001 到 336)
%w 星期几作为整数[0(星期日),6]
%u 从 1 开始的星期几整数,其中 1 是星期一。
%U 一年中的周数[00, 53]; 星期日被认为是一周的第一天,年初第一个星期日之前的日子被称为“第 0 周”
%W 一年中的周数[00, 53]; 星期一被认为是一周的第一天,年初第一个星期一之前的日子被称为“第 0 周”
%z UTC 时区偏移为+HHMM-HHMM; 如果时区是 naive,则为空
%Z 时区名称作为字符串,如果没有时区则为空字符串
%F %Y-%m-%d的快捷方式(例如,2012-4-18
%D %m/%d/%y的快捷方式(例如,04/18/12

您可以使用许多相同的格式代码使用datetime.strptime将字符串转换为日期(但是一些代码,如%F,不能使用):

In [29]: value = "2011-01-03"
In [30]: datetime.strptime(value, "%Y-%m-%d")
Out[30]: datetime.datetime(2011, 1, 3, 0, 0)
In [31]: datestrs = ["7/6/2011", "8/6/2011"]
In [32]: [datetime.strptime(x, "%m/%d/%Y") for x in datestrs]
Out[32]: 
[datetime.datetime(2011, 7, 6, 0, 0),
 datetime.datetime(2011, 8, 6, 0, 0)]

datetime.strptime 是一种解析具有已知格式的日期的方法。

pandas 通常面向处理日期数组,无论是作为轴索引还是数据框中的列。pandas.to_datetime方法解析许多不同类型的日期表示。标准日期格式如 ISO 8601 可以快速解析:

In [33]: datestrs = ["2011-07-06 12:00:00", "2011-08-06 00:00:00"]
In [34]: pd.to_datetime(datestrs)
Out[34]: DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00'], dtype='dat
etime64[ns]', freq=None)

它还处理应被视为缺失的值(None,空字符串等):

In [35]: idx = pd.to_datetime(datestrs + [None])
In [36]: idx
Out[36]: DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00', 'NaT'], dty
pe='datetime64[ns]', freq=None)
In [37]: idx[2]
Out[37]: NaT
In [38]: pd.isna(idx)
Out[38]: array([False, False,  True])

NaT(不是时间)是 pandas 中的时间戳数据的空值。

注意

dateutil.parser是一个有用但不完美的工具。值得注意的是,它会将一些字符串识别为日期,而您可能希望它不会;例如,"42"将被解析为年份2042与今天的日历日期相对应。

datetime对象还具有许多针对其他国家或语言系统的特定于区域的格式选项。例如,德国或法国系统上的缩写月份名称与英语系统上的不同。请参阅表 11.3 以获取列表。

表 11.3:特定于区域的日期格式化

类型 描述
%a 缩写的星期几名称
%A 完整的星期几名称
%b 缩写的月份名称
%B 完整的月份名称
%c 完整的日期和时间(例如,‘周二 2012 年 5 月 1 日 下午 04:20:57’)
%p AM 或 PM 的本地等效
%x 本地适用的格式化日期(例如,在美国,2012 年 5 月 1 日为‘05/01/2012’)

| %X | 本地适用的时间(例如,‘下午 04:24:12’) |


Python 数据分析(PYDA)第三版(五)(3)https://developer.aliyun.com/article/1482393

相关文章
|
1天前
|
SQL 数据可视化 数据挖掘
2024年8个Python高效数据分析的技巧。,2024年最新Python基础面试题2024
2024年8个Python高效数据分析的技巧。,2024年最新Python基础面试题2024
2024年8个Python高效数据分析的技巧。,2024年最新Python基础面试题2024
|
3天前
|
机器学习/深度学习 数据挖掘 Python
Python数据分析 | 泰坦尼克逻辑回归(下)
Python数据分析 | 泰坦尼克逻辑回归
7 1
|
3天前
|
机器学习/深度学习 数据挖掘 BI
Python数据分析 | 泰坦尼克逻辑回归(上)
Python数据分析 | 泰坦尼克逻辑回归
17 0
|
3天前
|
数据采集 数据挖掘 Python
Python数据分析 | 线性回归
Python数据分析 | 线性回归
14 1
|
4天前
|
机器学习/深度学习 数据采集 自然语言处理
10个 Python 小技巧,覆盖了90%的数据分析需求!_countries_lat_lon
10个 Python 小技巧,覆盖了90%的数据分析需求!_countries_lat_lon
|
4天前
|
数据采集 人工智能 数据挖掘
「一行分析」利用12000条招聘数据分析Python学习方向和就业方向
「一行分析」利用12000条招聘数据分析Python学习方向和就业方向
|
6天前
|
数据采集 数据可视化 数据挖掘
利用Python和Pandas库优化数据分析流程
在当今数据驱动的时代,数据分析已成为企业和个人决策的重要依据。Python作为一种强大且易于上手的编程语言,配合Pandas这一功能丰富的数据处理库,极大地简化了数据分析的流程。本文将探讨如何利用Python和Pandas库进行高效的数据清洗、转换、聚合以及可视化,从而优化数据分析的流程,提高数据分析的效率和准确性。
|
6天前
|
SQL 数据采集 数据挖掘
构建高效的Python数据处理流水线:使用Pandas和NumPy优化数据分析任务
在数据科学和分析领域,Python一直是最受欢迎的编程语言之一。本文将介绍如何通过使用Pandas和NumPy库构建高效的数据处理流水线,从而加速数据分析任务的执行。我们将讨论如何优化数据加载、清洗、转换和分析的过程,以及如何利用这些库中的强大功能来提高代码的性能和可维护性。
|
6天前
|
数据可视化 数据挖掘 BI
【Python】—— pandas 数据分析
【Python】—— pandas 数据分析
20 1
|
6天前
|
数据采集 数据可视化 数据挖掘
如何利用Python中的Pandas库进行数据分析和可视化
Python的Pandas库是一种功能强大的工具,可以用于数据分析和处理。本文将介绍如何使用Pandas库进行数据分析和可视化,包括数据导入、清洗、转换以及基本的统计分析和图表绘制。通过学习本文,读者将能够掌握利用Python中的Pandas库进行高效数据处理和可视化的技能。