当我更改 python pandas 数据框中的索引时,matplotlib 图表发生了变化
Posted
技术标签:
【中文标题】当我更改 python pandas 数据框中的索引时,matplotlib 图表发生了变化【英文标题】:The matplotlib chart changes when I change the index in python pandas dataframe 【发布时间】:2021-01-12 16:12:00 【问题描述】:我有一个 S&P500 历史价格数据集,其中包含日期、价格和其他我现在不需要用来解决我的问题的数据。
Date Price
0 1981.01 6.19
1 1981.02 6.17
2 1981.03 6.24
3 1981.04 6.25
. . .
and so on till 2020
日期是float
,带有年、点和月。
我尝试使用matplotlib.pyplot as plt
绘制所有历史价格。
plt.plot(df["Price"].tail(100))
plt.title("S&P500 Composite Historical Data")
plt.xlabel("Date")
plt.ylabel("Price")
这是结果。我使用了df["Price"].tail(100)
,因此您可以更好地看到第一张图和第二张图之间的差异(稍后您将看到)。
但后来我尝试将索引从前一个(0、1、2 等)设置为 DataFrame 中的df["Date"]
列,以便在 x 轴上查看日期。
df = df.set_index("Date")
plt.plot(df["Price"].tail(100))
plt.title("S&P500 Composite Historical Data")
plt.xlabel("Date")
plt.ylabel("Price")
这是结果,非常令人失望。 我有日期,它应该在 x 轴上,但问题是图表与之前的图表不同,而之前的图表是正确的。
如果您需要数据集来尝试问题here,您可以找到它。 它被称为美国股票市场 1871 年至今和 CAPE 比率。 希望你已经明白了一切。 提前致谢
更新
我发现了一些可能导致问题的原因。如果您深入查看日期,您会发现在第 10 个月,每个都写为浮点数(在原始数据集中),如下所示:示例 Year:1884 1884.1
。当您使用pd.to_datetime()
将Date
浮点系列转换为Datetime
时,会出现此问题。所以问题可能是 #10 月中的日期在转换为 Datetime
时变为:(之前的示例)1884-01-01 这是一年中的第一个月,并且它对最终情节有影响。
解决方案
终于解决了我的问题!
是的,错误是我在更新段落中解释的错误,所以我决定添加一个0
作为String
,其中日期(作为字符串)的长度为 6 以便更改,例如:1884.1 ==> 1884.10
df["len"] = df["Date"].apply(len)
df["Date"] = df["Date"].where(df["len"] == 7, df["Date"] + "0")
然后我删除我刚刚创建的 len 列。
df.drop(columns="len", inplace=True)
最后我将“日期”更改为Datetime
和pd.to_datetime
df["Date"] = pd.to_datetime(df["Date"], format='%Y.%m')
df = df.set_index("Date")
然后我开始绘制
df["Price"].tail(100).plot()
plt.title("S&P500 Composite Historical Data")
plt.xlabel("Date")
plt.ylabel("Price")
plt.show()
【问题讨论】:
如果您需要任何进一步的解释,请随时询问,我会很乐意回复 【参考方案1】:将df['Date']
视为float
并不是一个好主意。应该转换成pandasdatetime64[ns]
。这可以使用 pandas pd.to_datetime
方法来实现。
试试这个:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('ie_data.csv')
df=df[['Date','Price']]
df.dropna(inplace=True)
#converting to pandas datetime format
df['Date'] = df['Date'].astype(str).map(lambda x : x.split('.')[0] + x.split('.')[1])
df['Date'] = pd.to_datetime(df['Date'], format='%Y%m')
df.set_index(['Date'],inplace=True)
#plotting
df.plot() #full data plot
df.tail(100).plot() #plotting just the tail
plt.title("S&P500 Composite Historical Data")
plt.xlabel("Date")
plt.ylabel("Price")
plt.show()
输出:
【讨论】:
它不会改变任何东西。如果你绘制尾巴,你会看到结果是一样的)= 我的代码中有一个小错字。请你现在检查一下。如果它适合你,请勾选并投票。 我找到了解决方案。如果需要,请在我的问题中查看 太棒了!!但是,您的字符串解决方案可能会导致一些无法预料的错误。 pd.to_datetime 总是更好的解决方案。我想我的解决方案没有帮助?【参考方案2】:最简单的方法是将日期转换为实际的日期时间索引。这样matplotlib
将自动拾取并相应地绘制它。例如,给定您的日期格式,您可以这样做:
df["Date"] = pd.to_datetime(df["Date"].astype(str), format='%Y.%m')
df = df.set_index("Date")
plt.plot(df["Price"].tail(100))
目前,您展示的第一个图实际上是针对index
绘制Price
列,这似乎是从0 到1800 的常规范围索引等等。您建议您的数据从 1981 年开始,因此尽管每个观测值在 x 轴上均匀分布(间隔为 1,即从一个索引值跳转到下一个索引值)。这就是图表看起来合理的原因。然而 x 轴值却没有。
现在,当您将Date
(作为浮点数)设置为索引时,请注意您并未均匀覆盖例如 1981 和 1982 之间的时间间隔。您的值从 1981.1 到 1981.12 是均匀分布的,但是从 1981.12 到 1982 年什么都没有。这就是为什么第二张图表也按预期绘制的原因。如上所述将索引设置为 DatetimeIndex
应该可以消除此问题,因为 Matplotlib 将知道如何沿 x 轴均匀分布日期。
【讨论】:
我没有收到错误,但情节与错误的情节相似。阅读我在问题末尾写的“更新”,我解释了问题出在哪里 我找到了解决方案。我写的!【参考方案3】:我认为您的问题是您的 Date 是浮点类型,并且将其作为 x 轴完全符合将 ([2012.01, 2012.02, ..., 2012.12, 2013.01....])
类型的数组作为 x 轴的预期。您可以先将 Date 列转换为 DateTimeIndex,然后使用内置的 pandas plot 方法:
df["Price"].tail(100).plot()
【讨论】:
以上是关于当我更改 python pandas 数据框中的索引时,matplotlib 图表发生了变化的主要内容,如果未能解决你的问题,请参考以下文章
如何在python pandas数据框中选择和更改数据[重复]
python - 如何按python中的因子级别对pandas数据框中的行进行重新排序?
使用 Pandas 将数据框中的 Python 对象列转换为没有日期的时间