【问题标题】:plotting pandas dataframe date绘制熊猫数据框日期
【发布时间】:2020-01-14 07:31:54
【问题描述】:

我有一个包含 27 列用电量的 pandas 数据框,第一列表示两年内的日期和时间,其他列记录了两年内 26 所房屋的每小时用电量值。我正在做的是使用 k-means 进行聚类。每当我尝试在 x 轴上绘制日期和在 y 轴上绘制电力消耗值时,我都会遇到一个问题,即 x 和 y 必须具有相同的大小。我尝试重塑,但问题没有得到解决。

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt
import math
import datetime
data_consumption2 = pd.read_excel(r"C:\Users\user\Desktop\Thesis\Tarek\Parent.xlsx", sheet_name="Consumption")
data_consumption2['Timestamp'] = pd.to_datetime(data_consumption2['Timestamp'], unit='s')
X=data_consumption2.iloc[: , 1:26].values
X=np.nan_to_num(X)
np.concatenate(X)
date=data_consumption2.iloc[: , 0].values
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)
C = kmeans.cluster_centers_
plt.scatter(X, R , s=40, c= kmeans.labels_.astype(float), alpha=0.7)
plt.scatter(C[:,0] , C[:,1] , marker='*' , c='r', s=100)

我总是收到相同的错误消息,X 和 Y 必须有保存大小,尝试重塑您的数据。当我尝试重塑数据时它不起作用,因为日期列的大小总是小于其余列的大小。

【问题讨论】:

  • 你能展示你的桌子的一部分吗?
  • 是的,日期栏怎么能比其他栏短
  • 我在上面的问题中添加了一张照片
  • 实际上日期列更短,因为我将所有其余列“26”合并在一列“特征向量”中以将其传递给 k-means 算法跨度>
  • 日期列的大小实际上是相同的“16960 行”,但是由于我将其余列收集在一列中,因此日期列变得更短

标签: python python-3.x pandas cluster-analysis


【解决方案1】:

我认为您实际上所做的是对所有家庭进行时间序列聚类,以发现一段时间内相似的用电模式。

为此,每个时间戳都成为一个“特征”,而每个家庭的使用情况成为您的数据行。这将更容易应用 sklearn 聚类方法,这些方法通常采用method.fit(x) 的形式,其中x 表示特征(将数据作为具有(row, column) 形状的二维数组传递)。所以你的数据需要转置。

重构后的代码如下:

# what you have done 
import pandas as pd
df = pd.read_excel(r"C:\Users\user\Desktop\Thesis\Tarek\Parent.xlsx", sheet_name="Consumption")
df['Timestamp'] = pd.to_datetime(df['Timestamp'], unit='s')

# this is to fill all the NaN values with 0
df.fillna(0,inplace=True)

# transpose the dataframe accordingly
df = df.set_index('Timestamp').transpose()
df.rename(columns=lambda x : x.strftime('%D %H:%M:%S'), inplace=True)
df.reset_index(inplace=True)
df.rename(columns={'index':'house_no'}, inplace=True)
df.columns.rename(None, inplace=True)
df.head()

您应该会看到类似这样的内容(不要介意显示的数据,我创建了一些与您的相似的虚拟数据)。

接下来,对于集群,您可以这样做:

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=3)
kmeans.fit(df.iloc[:,1:])
y_kmeans = kmeans.predict(df.iloc[:,1:])
C = kmeans.cluster_centers_

# add a new column to your dataframe that contains the predicted clusters
df['cluster'] = y_kmeans

最后,对于绘图,您可以使用以下代码生成您想要的散点图:

import matplotlib.pyplot as plt

color = ['red','green','blue']

plt.figure(figsize=(16,4))

for index, row in df.iterrows():
    plt.scatter(x=row.index[1:-1], y=row.iloc[1:-1], c=color[row.iloc[-1]], marker='x', alpha=0.7, s=40)

for index, cluster_center in enumerate(kmeans.cluster_centers_):
    plt.scatter(x=df.columns[1:-1], y=cluster_center, c=color[index], marker='o', s=100)

plt.xticks(rotation='vertical')
plt.ylabel('Electricity Consumption')
plt.title(f'All Clusters - Scatter', fontsize=20)
plt.show()

但我建议为单个集群绘制线图,在视觉上更吸引人(对我而言):

plt.figure(figsize=(16,16))

for cluster_index in [0,1,2]:

    plt.subplot(3,1,cluster_index + 1)

    for index, row in df.iterrows():
        if row.iloc[-1] == cluster_index:
            plt.plot(row.iloc[1:-1], c=color[row.iloc[-1]], linestyle='--', marker='x', alpha=0.5)

    plt.plot(kmeans.cluster_centers_[cluster_index], c = color[cluster_index], marker='o', alpha=1)

    plt.xticks(rotation='vertical')
    plt.ylabel('Electricity Consumption')
    plt.title(f'Cluster {cluster_index}', fontsize=20)

plt.tight_layout()
plt.show()

干杯!

【讨论】:

  • 首先,你真好,谢谢你帮助我。其次,如果我想在特定的时间段内进行聚类并仅绘制 MON 和年份,该怎么办?
  • 在转置之前重新采样您的数据帧:df = df.resample('M', on='Timestamp').mean().transpose()。然后,如果您只想保留月份和年份,请重命名您的列:df.rename(columns=lambda x : x.strftime('%Y-%m'), inplace=True)。其余步骤相同。如果您不熟悉方法调用,请查看 Pandas 的文档。
  • 非常感谢您的帮助,我会做的
  • 最后一个问题,为什么每个集群都有多个中心?我希望它成为每个集群的一个中心,而不是更多,我该怎么做?
  • 每个时间步都被视为一个特征,因此 1 个数据具有 N 特征(取决于有多少时间步)。每个集群只有一个中心,但每个中心包含每个特征的值(因此集群中心将具有N 值。
猜你喜欢
  • 2018-11-08
  • 2013-01-08
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 2017-10-10
  • 2017-05-28
  • 2017-06-09
  • 2015-02-04
相关资源
最近更新 更多