Pandas 是一个强大的Python库,专为数据操作和分析而设计。Pandas 提供了高效的数据结构和数据分析工具,特别适合处理带有标签的数据。本文将详细介绍Pandas的基本功能和用法。
首先,确保你已经安装了Pandas库,如果没有安装,可以使用pip命令进行安装:
pip install pandas
然后,在你的Python脚本中导入Pandas:
- import pandas as pd
- pd.__version__
Pandas主要有两种数据结构:Series和DataFrame。Series是一维数组,DataFrame是二维数组。接下来我们将详细介绍这两种数据结构。
Series可以通过列表或数组创建:
- data_pd = pd.Series([0.25, 0.5, 0.75, 1.0])
- print("Pandas series from list: \n", data_pd)
-
- numpy_arr = np.arange(5)
- data_pd = pd.Series(numpy_arr)
- print("Pandas series from numpy array: \n", data_pd)
Series对象有许多有用的属性:
- print("Data values: ", data_pd.values)
- print("Data index: ", data_pd.index)
- print("Data[1]: ", data_pd[1])
- print("Data[-2:]: \n", data_pd[-2:])
-
- data_pd = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])
- print("Data['b']: ", data_pd['b'])
-
- index = ['a', 'b', 'c', 'd', 3]
- data_pd = pd.Series(numpy_arr, index=index)
- print("Index['a']: ", data_pd['a'])
- print("Index[3]: ", data_pd[3])
- some_population_dict = {'Chiangrai': 11111, 'Pathum Thani': 22222, 'Bangkok': 33333, 'Chiangmai': 44444}
- data_pd = pd.Series(some_population_dict)
- print("Population['Bangkok']: ", data_pd['Bangkok'])
- print("Population['Pathumthan':'Chiangmai']: \n", data_pd['Pathum Thani': 'Chiangmai'])
- data_pd['e'] = 99
- print("Data with e: \n", data_pd)
- print("a in data?: ", 'a' in data_pd)
- print("All keys: ", data_pd.keys())
- print("All items: ", list(data_pd.items()))
- print("All values: ", data_pd.values)
- print("Data[(data > 0.3) & (data < 0.8)]: \n", data_pd[(data_pd > 0.3) & (data_pd < 0.8)])
- print("Data[['a', 'e']]: \n", data_pd[['a', 'e']])
- data = pd.Series(['a', 'b', 'c'], index=(1, 3, 5))
- print("Data[1]: ", data[1])
- print("Data[1:3]: \n", data[1:3])
-
- print("Data loc [1]: ", data.loc[1])
- print("Data loc [1:3]: \n", data.loc[1:3])
- print("Data iloc [1]: ", data.iloc[1])
- print("Data iloc [1:3]: \n", data.iloc[1:3])
DataFrame是一种二维数组,可以通过多个方式创建,例如从字典、列表或Numpy数组。
- some_population_dict = {'Chiangrai': 11111, 'Pathum Thani': 22222, 'Bangkok': 33333, 'Chiangmai': 44444}
- some_area_dict = {'Chiangrai': 999, 'Pathum Thani': 888, 'Bangkok': 777, 'Chiangmai': 666, 'Syria': 333}
- states = pd.DataFrame({'population': some_population_dict, 'area': some_area_dict})
- print("Everything: ")
- print(states)
- print("Only Chiangrai to Bangkok: ")
- print(states['Chiangrai': 'Bangkok'])
-
- print("Only population column: ")
- print(states['Chiangrai': 'Bangkok']['population'])
- print(states['population']['Chiangrai': 'Bangkok'])
- print("Only area column with everything")
- print(states['area'])
- print(states[:]['area'])
- print("Index: ", states.index)
- print("Index[-1]: ", states.index[-1])
- print("Columns: ", states.columns)
- print("Columns[0:1]: ", states.columns[0:1])
- population_series = pd.Series(some_population_dict)
- pd_from_series = pd.DataFrame(population_series, columns=['population'])
- print("PD from series: \n", pd_from_series)
-
- data = [{'a': i, 'b': 2 * i} for i in range(3)]
- pd_from_list_dict = pd.DataFrame(data, index=[1, 2, 3])
- print("PD from list of dict: \n", pd_from_list_dict)
-
- data_numpy = np.random.rand(3, 2)
- index = ['a', 'b', 'c']
- columns = ['foo', 'bar']
- pd_from_numpy = pd.DataFrame(data_numpy, index=index, columns=columns)
- print("PD from numpy: \n", pd_from_numpy)
- data['density'] = data['pop'] / data['area']
- print(data)
-
- print("==First row using iloc==")
- print(data.iloc[0])
-
- print("==First three rows, first two columns using iloc==")
- print(data.iloc[:3, :2])
-
- print("==Use loc for explicit index==")
- print(data.loc[:'Bangkok', :'pop'])
-
- print("==chain iloc and loc==")
- print(data.loc[:'Bangkok'].iloc[:, :2])
-
- print("==masking + fancy==")
- print(data.loc[data.density > 20, ['pop', 'density']])
- import numpy as np
- print("==Fill na with 0==")
- print(df.fillna(0))
-
- print("==Fill all na with mean==")
- print(df.fillna(df.mean()))
-
- print("replace df.mean() for col 1 with in place")
- df[1].fillna(df[1].mean(), inplace=True)
- print(df)
-
- print("==Interpolate==")
- print(df.interpolate(method='values'))
- data_numpy = np.random.rand(3, 2)
- index = ['Bangkok', 'Chiangmai', 'Samut Prakan']
- columns = ['Population', 'Area']
- pd_from_numpy = pd.DataFrame(data_numpy, index=index, columns=columns)
- print("==First dataframe==")
- print(pd_from_numpy)
-
- data_numpy2 = np.random.rand(4, 3)
- index2 = ['Bangkok', 'Chiangmai', 'Samut Prakan', 'Pathum Thani']
- columns2 = ['HDI', 'Temperature', 'GDP']
- pd_from_numpy2 = pd.DataFrame(data_numpy2, index=index2, columns=columns2)
- print("==Second dataframe==")
- print(pd_from_numpy2)
-
- print("==Normal concat along axis 1==")
- print(pd.concat([pd_from_numpy, pd_from_numpy2], axis=1))
-
- print("==Concat with join inner==")
- print(pd.concat([pd_from_numpy, pd_from_numpy2], axis=1, join='inner'))
- left = pd.DataFrame({'ID': ['001', '002', '003', '005'], 'DS': ['B', 'B', 'B', 'C+'], 'SAD': ['A', 'B', 'C+', 'F']})
- right = pd.DataFrame({'ID': ['001', '002', '003', '004'], 'HCI': ['B+', 'A', 'A', 'B+'], 'SDQI': ['A', 'A', 'B+', 'B']})
- result = pd.merge(left, right, on='ID')
- print(result)
-
- result = pd.merge(left, right, on='ID', how="outer")
- print(result)
-
- result = pd.merge(left, right, on='ID', how="left")
- print(result)
- df = pd.DataFrame([('bird', 'Falconiformes', 389.0), ('bird', 'Psittaciformes', 24.0), ('mammal', 'Carnivora', 80.2), ('mammal', 'Primates', np.nan), ('mammal', 'Carnivora', 58)], index=['falcon', 'parrot', 'lion', 'monkey', 'leopard'], columns=('class', 'order', 'max_speed'))
- grouped = df.groupby('class')
- print(grouped.sum())
-
- grouped = df.groupby('order')
- print(grouped.sum())
-
- grouped = df.groupby(['class', 'order'])
- print(grouped.sum())
-
- print(df.groupby(['class'])['max_speed'].median())
-
- import seaborn as sns
- planets = sns.load_dataset('planets')
- print(planets.groupby('method').sum())
- print(planets.groupby('method')['orbital_period'].median())
Pandas提供了强大的时间序列处理功能,可以方便地进行时间序列的操作和分析。
- date = pd.to_datetime("2015-07-04")
- print(type(date))
- date.strftime('%A')
-
- date + pd.to_timedelta(np.arange(12), 'D')
-
- index = pd.to_datetime(['2014-07-04', '2014-08-04', '2015-07-04', '2015-08-04'])
- data = pd.DataFrame(np.random.rand(4,2), index=index, columns=['Apple', 'Orange'])
- print(data)
-
- print(data['2014-07-04':'2015-07-04'])
- print(data['2015'])
- pd.date_range('2015-07-03', '2015-07-10')
- pd.date_range('2015-07-03', periods = 8)
- pd.date_range('2015-07-03', periods = 8, freq='H')
- pd.date_range('2015-07-03', periods = 18, freq='MS')
- pd.date_range('2015-07-03', periods = 18, freq='2H30T')
- from pandas_datareader import data
- import matplotlib.pyplot as plt
-
- goog = data.DataReader('GOOG', start='2004', end='2016', data_source='yahoo')
- goog_close = goog['Close']
- goog_close.plot()
-
- goog_close.plot(alpha=0.2, style='-')
- goog_close.resample('BA').mean().plot(style='o')
- goog_close.asfreq('BA').plot(style='--')
- rolling = goog_close.rolling(365, center = True)
- data = pd.DataFrame({'input': goog_close, 'one_year rolling mean': rolling.mean(), 'one_year rolling std': rolling.std()})
- data.plot(style=['-', '--', ':'])
- data = pd.read_csv('data/FremontBridge.csv', index_col='Date', parse_dates=True)
- data.columns = ['West', 'East']
- data['Total'] = data['East'] + data['West']
- data.fillna(0, inplace=True)
-
- weekly = data.resample('W').agg('sum')
- weekly.plot(style=[":", "--", '-'])
- plt.ylabel('Weekly bicycle count')
-
- by_time = data.groupby(data.index.time).mean()
- by_time.plot()
-
- by_day = data.groupby(data.index.dayofweek).mean()
- by_day.index = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun']
- by_day.plot(style=[':', '--', '-'])
将数据文件夹中的 "howlongwelive.csv" 文件加载到 DataFrame 中 提示:Reproducibility Tips: Absolute vs. relative paths | Kaggle
打印前两行和最后两行数据
打印 DataFrame 的形状
打印特征(列)名称
使用 .describe() 打印数据摘要
由于 Hepatatis B 列有很多空值,并且与 Diptheria 高度相关,删除 Hepatatis 列。另外,由于 Population 列有太多空值,也将其删除
将 Status 转换为 0 或 1(0 表示 Developing,1 表示 Developed)
将列名 thinness 1-19 years 重命名为 thinness 10-19 years
获取除 Life Expectancy 外的所有列,并转换为名为 X 的 numpy 数组
获取 Life Expectancy 列并转换为名为 y 的 numpy 数组
- import pandas as pd
-
- # 1. 将数据文件夹中的 "howlongwelive.csv" 文件加载到 DataFrame 中
- df = pd.read_csv('data/howlongwelive.csv')
-
- # 2. 打印前两行和最后两行数据
- print("前两行数据:")
- print(df.head(2))
- print("最后两行数据:")
- print(df.tail(2))
-
- # 3. 打印 DataFrame 的形状
- print("DataFrame 的形状:", df.shape)
-
- # 4. 打印特征(列)名称
- print("特征(列)名称:", df.columns)
-
- # 5. 使用 .describe() 打印数据摘要
- print("数据摘要:")
- print(df.describe())
-
- # 6. 由于 Hepatatis B 列有很多空值,并且与 Diptheria 高度相关,删除 Hepatatis 列。另外,由于 Population 列有太多空值,也将其删除
- df.drop(['Hepatatis B', 'Population'], axis=1, inplace=True)
-
- # 7. 将 Status 转换为 0 或 1(0 表示 Developing,1 表示 Developed)
- df['Status'] = df['Status'].apply(lambda x: 0 if x == 'Developing' else 1)
-
- # 8. 将列名 thinness 1-19 years 重命名为 thinness 10-19 years
- df.rename(columns={'thinness 1-19 years': 'thinness 10-19 years'}, inplace=True)
-
- # 9. 获取除 Life Expectancy 外的所有列,并转换为名为 X 的 numpy 数组
- X = df.drop('Life expectancy ', axis=1).values
-
- # 10. 获取 Life Expectancy 列并转换为名为 y 的 numpy 数组
- y = df['Life expectancy '].values
- import numpy as np
-
- print("np.nan 的类型:", type(np.nan))
- print("np.nan 减 1 的结果:", np.nan - 1) # 任何与 nan 进行的运算结果仍然是 nan
-
- vals2 = np.array([1, np.nan, 3, 4])
- print("Sum:", vals2.sum())
- print("Nansum:", np.nansum(vals2))
- print("Nanmin:", np.nanmin(vals2))
- print("Nanmax:", np.nanmax(vals2))
- import pandas as pd
-
- dfs = pd.Series([1, None, np.nan])
- print("Pandas 自动将 None 转换为 nan")
- print(dfs)
-
- dfs = pd.Series(["Hello", None, np.nan])
- print("Pandas 不会转换,因为字符串是对象")
- print(dfs)
-
- dfs = pd.Series([True, None, np.nan])
- print("Pandas 不会转换,布尔值被强制转换为对象")
- print(dfs)
- dfs = pd.Series([1, np.nan, "hello", None])
- print("是否为空值:", dfs.isnull())
- print("仅显示非空数据")
- print(dfs[dfs.notnull()])
- print("删除所有空值")
- print(dfs.dropna()) # 这不是就地操作
- print(dfs) # 这将返回旧的副本
-
- # 删除包含空值的列,使用 axis = 1
- df = pd.DataFrame([[1, np.nan, 2],
- [2, 3, 5],
- [np.nan, 4, np.nan],
- [4, np.nan, np.nan]])
-
- print(df.dropna(axis=1)) # 默认 axis = 0
-
- # 如果所有值都是 nan,则删除列
- df[3] = np.nan # 创建新列
- print(df.dropna(axis=1, how="all"))
- # 用 0 填充所有空值
- print("用 0 填充所有空值")
- print(df.fillna(0)) # 这不是就地操作
-
- # 用平均值填充所有空值
- print("用平均值填充所有空值")
- print(df.fillna(df.mean()))
-
- # 用平均值替换第 1 列的缺失值并就地操作
- df[1].fillna(df[1].mean(), inplace=True)
- print(df)
-
- # 用插值法填充缺失值
- print("用插值法填充缺失值")
- print(df.interpolate(method='values'))
- data_numpy = np.random.rand(3, 2) # 形状为 3x2
- index = ['Bangkok', 'Chiangmai', 'Samut Prakan']
- columns = ['Population', 'Area']
- pd_from_numpy = pd.DataFrame(data_numpy, index=index, columns=columns)
- print("第一个 DataFrame:")
- print(pd_from_numpy)
-
- data_numpy2 = np.random.rand(4, 3)
- index2 = ['Bangkok', 'Chiangmai', 'Samut Prakan', 'Pathum Thani']
- columns2 = ['HDI', 'Temperature', 'GDP']
- pd_from_numpy2 = pd.DataFrame(data_numpy2, index=index2, columns=columns2)
- print("第二个 DataFrame:")
- print(pd_from_numpy2)
-
- # 正常连接(沿轴 1)
- print("沿轴 1 正常连接:")
- print(pd.concat([pd_from_numpy, pd_from_numpy2], axis=1)) # 默认 join='outer',即完全外连接
-
- # 内连接
- print("内连接:")
- print(pd.concat([pd_from_numpy, pd_from_numpy2], axis=1, join='inner'))
- left = pd.DataFrame({'ID': ['001', '002', '003', '005'],
- 'DS': ['B', 'B', 'B', 'C+'],
- 'SAD': ['A', 'B', 'C+', 'F']})
- print("左表:")
- print(left)
-
- right = pd.DataFrame({'ID': ['001', '002', '003', '004'],
- 'HCI': ['B+', 'A', 'A', 'B+'],
- 'SDQI': ['A', 'A', 'B+', 'B']})
- print("右表:")
- print(right)
-
- # 内连接
- result = pd.merge(left, right, on='ID') # 默认 how='inner'
- print("内连接结果:")
- print(result)
-
- # 外连接
- result = pd.merge(left, right, on='ID', how="outer")
- print("外连接结果:")
- print(result)
-
- # 左连接
- result = pd.merge(left, right, on='ID', how="left")
- print("左连接结果:")
- print(result)
- df = pd.DataFrame([('bird', 'Falconiformes', 389.0),
- ('bird', 'Psittaciformes', 24.0),
- ('mammal', 'Carnivora', 80.2),
- ('mammal', 'Primates', np.nan),
- ('mammal', 'Carnivora', 58)],
- index=['falcon', 'parrot', 'lion', 'monkey', 'leopard'],
- columns=('class', 'order', 'max_speed'))
- print("DataFrame:")
- print(df)
-
- grouped = df.groupby('class') # 返回一个 DataFrameGroupBy 对象
- print("按 class 分组求和:")
- print(grouped.sum())
-
- grouped = df.groupby('order')
- print("按 order 分组求和:")
- print(grouped.sum())
-
- grouped = df.groupby(['class', 'order'])
- print("按 class 和 order 分组求和:")
- print(grouped.sum())
-
- print("按 class 分组求中位数:")
- print(df.groupby(['class'])['max_speed'].median())
- import pandas as pd
- import numpy as np
-
- # 1. 继续使用 "howlongwelive.csv" 文件,检查每列有多少缺失数据
- df = pd.read_csv('data/howlongwelive.csv')
- print("每列缺失数据的数量:")
- print(df.isnull().sum())
-
- # 2. 使用均值填充所有缺失数据
- df.fillna(df.mean(), inplace=True)
-
- # 3. 按国家分组,计算平均预期寿命
- grouped_by_country = df.groupby('Country')['Life expectancy '].mean()
- print("平均预期寿命最低的国家:", grouped_by_country.idxmin(), grouped_by_country.min())
- print("平均预期寿命最高的国家:", grouped_by_country.idxmax(), grouped_by_country.max())
-
- # 4. 按状态分组,计算平均预期寿命
- grouped_by_status = df.groupby('Status')['Life expectancy '].mean()
- print("按状态分组的平均预期寿命:")
- print(grouped_by_status)
-
- # 5. 创建另一个包含两列的数据框
- noise_level = np.random.rand(len(df['Country'].unique()))
- additional_df = pd.DataFrame({'Country': df['Country'].unique(), 'Noise_level': noise_level})
-
- # 6. 根据 ID 列合并这两个数据集
- merged_df = pd.merge(df, additional_df, on='Country')
- print("合并后的 DataFrame:")
- print(merged_df.head())
Pandas 是在金融建模的背景下开发的,因此它包含了一整套处理日期、时间和时间索引数据的工具。首先让我们了解 Python 如何处理日期和时间。
- from datetime import datetime
- datetime(year=2025, month=7, day=4)
使用 dateutil 模块,可以从各种字符串格式解析日期。
- from dateutil import parser
- date = parser.parse("4th of July, 2015")
- date
一旦你有了一个 datetime 对象,就可以做一些事情,比如打印星期几:
date.strftime('%A, %D')
我们可以类似地创建 numpy 类型的日期时间,它是一种非常有效的存储日期时间的方法。
- date = np.array('2015-07-04', dtype=np.datetime64) # ISO 日期
- date
由于其 numpy 类型,我们可以快速对其进行矢量化操作。
date + np.arange(12)
Pandas 使用 Timestamp 对象,它结合了 datetime 和 dateutil 的易用性以及 numpy.datetime64 的高效存储和矢量化接口。从这些 Timestamp 对象组中,Pandas 可以构建 DatetimeIndex,可用于索引 Series 或 DataFrame 中的数据。
- import pandas as pd
- date = pd.to_datetime("2015-07-04")
- print(type(date))
- date.strftime('%A')
使用 pd.to_timedelta 可以执行 numpy 风格的矢量化操作。
date + pd.to_timedelta(np.arange(12), 'D') # 单位是纳秒,不支持 Y 和 M,因为每个月的纳秒数不相等
当你开始通过时间戳索引数据时,Pandas 的时间序列工具真正变得有用。例如,我们可以构建一个具有时间索引数据的 Series 对象:
- index = pd.to_datetime(['2014-07-04', '2014-08-04', '2015-07-04', '2015-08-04'])
- data = pd.DataFrame(np.random.rand(4, 2), index=index, columns=['Apple', 'Orange'])
- data
使用切片访问行:
data['2014-07-04':'2015-07-04']
有特殊的日期索引,例如传递年份:
data['2015']
一个有用的方法是 date_range,它生成从指定开始和结束的日期:
pd.date_range('2015-07-03', '2015-07-10')
我们可以指定周期而不是结束:
pd.date_range('2015-07-03', periods=8)
如果我们想要 8 个周期,但以小时为单位,我们使用 freq 参数:
pd.date_range('2015-07-03', periods=8, freq='H')
- from pandas_datareader import data
-
- goog = data.DataReader('GOOG', start='2004', end='2016', data_source='yahoo')
- goog.head()
-
- import matplotlib.pyplot as plt
-
- goog_close = goog['Close']
- goog_close.plot()
时间序列数据的一个常见需求是以更高或更低的频率重新采样。这可以使用 resample() 方法,或更简单的 asfreq() 方法来完成。这两者之间的主要区别是 resample() 本质上是数据聚合,而 asfreq() 本质上是数据选择。
让我们看看 Google 收盘价,当我们对数据进行降采样时,两者返回的结果有什么不同。在这里,我们将在营业年末对数据进行重新采样:
- goog_close.plot(alpha=0.2, style='-')
- goog_close.resample('BA').mean().plot(style='o') # BA = 营业年末
- goog_close.asfreq('BA').plot(style='--')
请注意区别:在每个点,resample 报告前一年的平均值,而 asfreq 报告年末的值。
橙色点表示 goog_close.resample(),绿色虚线表示 goog_close.asfreq()。
resample 和 asfreq 之间的区别:
- ts = pd.Series(range(365), index=pd.date_range(start='20190101', end='20191231', freq='D'))
- ts.head()
ts.asfreq(freq='Q') # 季度
这不是每个季度的平均值,而是每个季度最后一天的平均值:
Pandas 有两个密切相关的方法:shift() 和 tshift()。简而言之,两者的区别在于 shift() 移动数据,而 tshift() 移动索引。在两种情况下,移动是以频率的倍数指定的。这里我们将同时移动 900 天:
- fig, ax = plt.subplots(3, sharey=True)
-
- goog_close = goog_close.asfreq('D', method='pad')
-
- goog_close.plot(ax=ax[0])
- goog_close.shift(900).plot(ax=ax[1])
- goog_close.tshift(900).plot(ax=ax[2])
为什么要移动?
一个常见的上下文是计算一段时间内的差异。例如,我们使用移动后的值来计算 Google 股票在数据集期间的一年投资回报率:
- ROI = 100 * (goog_close.tshift(-365) / goog_close)
- ROI.plot()
- plt.ylabel('Return on Investment')
这有助于我们看到 Google 股票的整体趋势:迄今为止,投资 Google 最有利可图的时间是其 IPO 后不久和 2009 年中期的经济衰退。
- rolling = goog_close.rolling(365, center=True)
- rolling
-
- data = pd.DataFrame({'input': goog_close, 'one_year rolling mean': rolling.mean(), 'one_year rolling std': rolling.std()})
- data.plot(style=['-', '--', ':'])
示例:可视化西雅图自行车计数
- data = pd.read_csv('data/FremontBridge.csv')
- data = pd.read_csv('data/FremontBridge.csv', index_col='Date', parse_dates=True)
- data.head()
-
- data.columns = ['West', 'East']
- data.head()
-
- data.isna().sum()
- data.fillna(0, inplace=True)
-
- data['Total'] = data['East'] + data['West']
- data.head()
- import pandas as pd
- import matplotlib.pyplot as plt
- from pandas_datareader import data
-
- # 1. 加载 "data/appl_1980_2014.csv" 文件
- df = pd.read_csv('data/appl_1980_2014.csv')
-
- # 2. 将 Date 列转换为 datetime 类型
- df['Date'] = pd.to_datetime(df['Date'])
-
- # 3. 过滤掉年份小于 1987 的数据
- df = df[df['Date'].dt.year >= 1987]
-
- # 4. 按升序排序索引(最早的日期在前)
- df.sort_index(ascending=True, inplace=True)
-
- # 5. 获取每列的平均值,在每个月的最后一个工作日进行重采样(即 BM)
- monthly_avg = df.resample('BM', on='Date').mean()
-
- # 6. 我们的数据中有多少个月?
- num_months = len(monthly_avg)
- print(f"数据中的月份数量: {num_months}")
-
- # 7. 使用 shift() 比较今年与去年 High 列的差异,绘制图表
- monthly_avg['High_diff'] = monthly_avg['High'].diff(12)
- plt.figure(figsize=(10, 6))
- plt.plot(monthly_avg.index, monthly_avg['High_diff'], label='High Difference')
- plt.xlabel('Date')
- plt.ylabel('Difference in High')
- plt.title('Year-over-Year Difference in High Price')
- plt.legend()
- plt.show()
-
- # 8. 对 Close 列执行窗口大小为 100 天的滚动平均
- df['Close_MA100'] = df['Close'].rolling(window=100).mean()
- plt.figure(figsize=(10, 6))
- plt.plot(df['Date'], df['Close'], label='Close Price')
- plt.plot(df['Date'], df['Close_MA100'], label='100-Day Moving Average')
- plt.xlabel('Date')
- plt.ylabel('Price')
- plt.title('Apple Close Price and 100-Day Moving Average')
- plt.legend()
- plt.show()
-
- # 9. 加载微软数据并比较回报率
- microsoft = data.DataReader('MSFT', start='1987', end='2014', data_source='yahoo')
- apple_2000_onward = df[df['Date'].dt.year >= 2000].copy()
- microsoft_2000_onward = microsoft[microsoft.index.year >= 2000].copy()
-
- apple_2000_onward['Return'] = apple_2000_onward['Close'] / apple_2000_onward['Close'].iloc[0]
- microsoft_2000_onward['Return'] = microsoft_2000_onward['Close'] / microsoft_2000_onward['Close'].iloc[0]
-
- plt.figure(figsize=(10, 6))
- plt.plot(apple_2000_onward['Date'], apple_2000_onward['Return'], label='Apple Return')
- plt.plot(microsoft_2000_onward.index, microsoft_2000_onward['Return'], label='Microsoft Return')
- plt.xlabel('Date')
- plt.ylabel('Return Rate')
- plt.title('Apple vs Microsoft Return Rate (2000 Onward)')
- plt.legend()
- plt.show()
结语
在本篇文章中,我们详细介绍了 Pandas 的基础知识,包括 Series 和 DataFrame 的创建、索引、切片、合并和聚合操作等。我们通过实际的代码示例演示了如何使用 Pandas 进行数据处理和分析,并完成了几个实际任务,以帮助大家更好地理解和掌握这些操作。
通过这些内容,我们可以看到 Pandas 强大的数据处理能力,它不仅能够处理结构化数据,还能够与其他科学计算库(如 NumPy)无缝集成。Pandas 提供的这些功能,使得我们能够更高效地进行数据清洗、转换和分析,从而在数据科学项目中发挥重要作用。
下一篇文章将介绍数据可视化工具——Matplotlib。我们将学习如何使用Matplotlib创建各种图表,以更直观地展示数据分析的结果。敬请期待!
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!