当我更改 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)

最后我将“日期”更改为Datetimepd.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 pandas数据框中选择和更改数据[重复]

python - 如何按python中的因子级别对pandas数据框中的行进行重新排序?

使用 Pandas 将数据框中的 Python 对象列转换为没有日期的时间

如何在 Pandas 数据框中的特定位置插入一列? (更改熊猫数据框中的列顺序)

如何更改 Pandas 数据框中的日期格式? [复制]