如何将宽数据框转换为绘图特定数据

2024-05-29 10:13:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧,如下所示:

import pandas as pd

# sample data
# sample data
data = {'RowName': ['A1', 'A2', 'A3'], '20/09/21 (LP%)': [120, 0, 0], '20/09/21 (Vol)': [13, 1, 31], '20/09/21 (OI)': [0, 0, 0], '21/09/21 (LP%)': [135.0, 143.43, 143.43], '21/09/21 (Vol)': [68.6, 63.81, 58.1], '21/09/21 (OI)': [0, 0, 0], '22/09/21 (LP%)': [130, 0, 0], '22/09/21 (Vol)': [0, 0, 0], '22/09/21 (OI)': [75, 80, 85]}
df = pd.DataFrame(data)

# display(df)
  RowName  20/09/21 (LP%)  20/09/21 (Vol)  20/09/21 (OI)  21/09/21 (LP%)  21/09/21 (Vol)  21/09/21 (OI)  22/09/21 (LP%)  22/09/21 (Vol)  22/09/21 (OI)
0      A1             120              13              0          135.00           68.60              0             130               0             75
1      A2               0               1              0          143.43           63.81              0               0               0             80
2      A3               0              31              0          143.43           58.10              0               0               0             85

使用matplotlib和pandas中的以下数据帧,是否有打印的方法:

  • x轴:其中包含(LP%)的列-以日期为准,并使用这些列中的每一列作为x轴上的点

    我选择了使用以下内容的列:

    df2 = df.filter(regex='LP%')
    
  • y轴:仅A1行的实际值

大概是这样的:

enter image description here


Tags: 数据sampleimporta2dataframepandasdfdata
3条回答

您需要首先重塑数据帧。从如下数据帧开始:

  RowName  20/09/21 (LP%)  20/09/21 (Vol)  20/09/21 (OI)  21/09/21 (LP%)  21/09/21 (Vol)  21/09/21 (OI)  22/09/21 (LP%)  22/09/21 (Vol)  22/09/21 (OI)
0      A1             120              13              0          135.00           68.60              0             130               0             75
1      A2               0               1              0          143.43           63.81              0               0               0             80
2      A3               0              31              0          143.43           58.10              0               0               0             85

您可以使用以下工具重新塑造形状:

# row filter
df = df.iloc[:1, :]

# column filter and transpose
df = df[[col for col in df.columns if '(LP%)' in col]].T

# convert column name to datetime value
df.index = pd.to_datetime(df.index.map(lambda x: x.split(' ')[0]))

# pass a sting as label
df.columns = ['value']

然后,您可以简单地使用以下工具进行绘图:

df.plot()

plt.show()

完整代码

import pandas as pd
import matplotlib.pyplot as plt


df = pd.read_csv(r'data/data.csv')


df = df.iloc[:1, :]
df = df[[col for col in df.columns if '(LP%)' in col]].T
df.index = pd.to_datetime(df.index.map(lambda x: x.split(' ')[0]))
df.columns = ['value']

df.plot()

plt.show()

enter image description here


您可以使用以下工具进一步自定义日期时间轴:

import matplotlib.dates as md

fig, ax = plt.subplots()

ax.plot(df.index, df['value'])

ax.set_xlabel('Date')
ax.set_ylabel('LP Value')

ax.xaxis.set_major_locator(md.DayLocator(interval = 1))
ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 0)
ax.set_xlim([df.index[0], df.index[-1]])

plt.show()

enter image description here

查看您的数据帧(假设它名为df),我认为最快的方法是转置它,因为您希望使用行作为列:

df_trans = df.transpose() #or df.T
df_trans.plot.line(x='RowName', y='A1', color='red')
import matplotlib.pyplot as plt
plt.show() 

可能要重命名'Rowname'列:

df_trans.rename({0: 'LP'}, axis=1)
df_trans.plot.line(x='LP', y='A1', color='red')
import matplotlib.pyplot as plt
plt.show()
  • 当前实现的问题是,您只获得'A1'的结果,然后可能需要重复代码来获取其他数据
  • ^{}将允许转换日期后带有存根的所有列。
    • 这要求存根位于前面,可以通过列名上的列表进行调整
    • suffix='\d+\/\d+\/\d+'与要提取的日期格式匹配
  • 一旦数据帧被转换,就更容易使用和访问所有数据
  • 使用^{}重塑数据以绘制'(LP%)'
  • 直接用^{}绘图
    • 线形图x轴数据格式为%M-%D %H,因为只有少量数据。当有更多天的数据时,格式将更新
    • 索引将是x轴,因此无需指定x=
    • 使用y=指定列名,或者不使用它,所有列都将被打印
  • python 3.8.11pandas 1.3.2matplotlib 3.4.3seaborn 0.11.2
import pandas as pd

# sample data
data = {'RowName': ['A1', 'A2', 'A3'], '20/09/21 (LP%)': [120, 0, 0], '20/09/21 (Vol)': [13, 1, 31], '20/09/21 (OI)': [0, 0, 0], '21/09/21 (LP%)': [135.0, 143.43, 143.43], '21/09/21 (Vol)': [68.6, 63.81, 58.1], '21/09/21 (OI)': [0, 0, 0], '22/09/21 (LP%)': [130, 0, 0], '22/09/21 (Vol)': [0, 0, 0], '22/09/21 (OI)': [75, 80, 85]}
df = pd.DataFrame(data)

# adjust the column names so the stub is before the date
df.columns = [' '.join(col.split(' ')[::-1]) if len(col.split(' ')) > 1 else col for col in df.columns]

# convert to long form
df = pd.wide_to_long(df, stubnames=['(LP%)', '(Vol)', '(OI)'], i=['RowName'], sep=' ', j='Date', suffix='\d+\/\d+\/\d+').reset_index()

# convert the Date column to a datetime dtype
df.Date = pd.to_datetime(df.Date).dt.date

# display(df.head())
  RowName        Date   (LP%)  (Vol)  (OI)
0      A1  2021-09-20  120.00  13.00     0
1      A2  2021-09-20    0.00   1.00     0
2      A3  2021-09-20    0.00  31.00     0
3      A1  2021-09-21  135.00  68.60     0
4      A2  2021-09-21  143.43  63.81     0

# pivot the LP% column
dlp = df.pivot(index='Date', columns='RowName', values='(LP%)')

# display(dlp)
RowName        A1      A2      A3
Date                             
2021-09-20  120.0    0.00    0.00
2021-09-21  135.0  143.43  143.43
2021-09-22  130.0    0.00    0.00

# plot any specific column
dlp.plot(y=['A1'], rot=0, figsize=(10, 5), marker='o', title='LP%: A1')

enter image description here

# or all 3
dlp.plot(rot=0, figsize=(10, 5), marker='o', title='LP%')
  • 'A3'行覆盖了'A2'行,因为数据是相同的

enter image description here

# specify the kind parameter for a bar plot
dlp.plot(kind='bar', rot=0, figsize=(10, 5), title='LP%')

enter image description here

  • 再添加一个步骤,并使用^{}df重塑为一个完整的长格式,以便使用^{}轻松绘制所有数据。
    • seaborn是{}的高级API
import seaborn as sns

# melt
dfm = df.melt(id_vars=['RowName', 'Date'])

# display(dfm.head())
  RowName        Date variable   value
0      A1  2021-09-20    (LP%)  120.00
1      A2  2021-09-20    (LP%)    0.00
2      A3  2021-09-20    (LP%)    0.00
3      A1  2021-09-21    (LP%)  135.00
4      A2  2021-09-21    (LP%)  143.43

# plot
sns.relplot(kind='line', data=dfm, x='Date', y='value', marker='o', row='variable', hue='RowName', height=3.5, aspect=2.25)

enter image description here

相关问题 更多 >

    热门问题