5

我想为pandas包含带有数字的列和其他包含字符串作为值的列的 DataFrame 绘制平行坐标。

问题描述

我有以下测试代码,可用于绘制带有数字的平行坐标:

import pandas as pd
import matplotlib.pyplot as plt
from pandas.tools.plotting import parallel_coordinates

df = pd.DataFrame([["line 1",20,30,100],\
    ["line 2",10,40,90],["line 3",10,35,120]],\
    columns=["element","var 1","var 2","var 3"])
parallel_coordinates(df,"element")
plt.show()

最终显示以下图形: 在此处输入图像描述

但是我想尝试的是在我的情节中添加一些具有字符串的变量。但是当我运行以下代码时:

df2 = pd.DataFrame([["line 1",20,30,100,"N"],\
    ["line 2",10,40,90,"N"],["line 3",10,35,120,"N-1"]],\
    columns=["element","var 1","var 2","var 3","regime"])
parallel_coordinates(df2,"element")
plt.show()

我收到此错误:

ValueError:float()的无效文字:N

我想这意味着parallel_coordinates函数不接受字符串。

我正在尝试做的示例

我正在尝试做类似这个例子的事情,其中​​ Race 和 Sex 是字符串而不是数字:

包含字符串值的平行坐标图

问题

有没有办法使用 执行这样的图形pandas parallel_coordinates?如果没有,我怎么能尝试这样的图形?也许与matplotlib

我必须提到我特别在Python 2.5下寻找 带有 pandas 版本的解决方案0.9.0

4

2 回答 2

5

我并不完全清楚你想用这个regime专栏做什么。

如果问题只是它的存在阻止了绘图显示,那么您可以简单地从绘图中省略有问题的列:

parallel_coordinates(df2, class_column='element', cols=['var 1', 'var 2', 'var 3'])

在此处输入图像描述

查看您提供的示例,然后我了解到您希望以某种方式将分类变量放置在垂直线上,并且该类别的每个值都由不同的 y 值表示。我做对了吗?

如果我是,那么您需要将您的分类变量(此处为regime)转换为数值。为此,我使用了在这个网站上找到的这个技巧。

df2.regime = df2.regime.astype('category')
df2['regime_encoded'] = df2.regime.cat.codes


print(df2)
    element var 1   var 2   var 3   regime  regime_encoded
0   line 1  20      30      100     N       0
1   line 2  10      40      90      N       0
2   line 3  10      35      120     N-1     1

此代码创建一个新列 ( regime_encoded),其中类别制度的每个值都由一个整数编码。然后,您可以绘制新数据框,包括新创建的列:

parallel_coordinates(df2[['element', 'var 1', 'var 2', 'var 3', 'regime_encoded']],"element")

在此处输入图像描述

问题是分类变量 (0, 1) 的编码值与其他变量的范围无关,因此所有行似乎都趋向于同一点。答案是与数据范围相比缩放编码(这里我这样做非常简单,因为您的数据介于 0 和 120 之间,如果您的真实数据帧不是这种情况,您可能需要从最小值开始缩放)。

df2['regime_encoded'] = df2.regime.cat.codes * max(df2.max(axis=1, numeric_only=True))
parallel_coordinates(df2[['element', 'var 1', 'var 2', 'var 3', 'regime_encoded']],"element")

在此处输入图像描述

为了更好地适应您的示例,您可以添加注释:

df2['regime_encoded'] = df2.regime.cat.codes * max(df2.max(axis=1, numeric_only=True)
parallel_coordinates(df2[['element', 'var 1', 'var 2', 'var 3', 'regime_encoded']],"element")
ax = plt.gca()
for i,(label,val) in df2.loc[:,['regime','regime_encoded']].drop_duplicates().iterrows():
    ax.annotate(label, xy=(3,val), ha='left', va='center')

在此处输入图像描述

于 2017-07-13T13:26:27.427 回答
0

基于@Diziet 的回答,为了能够在Python 2.5下获得所需的图形,我们可以使用以下代码:

import pandas as pd
import matplotlib.pyplot as plt
from pandas.tools.plotting import parallel_coordinates

def format(input):
    if input == "N":
        output = 0
    elif input == "N-1":
        output = 1
    else:
        output = None
    return output

df2 = pd.DataFrame([["line 1",20,30,100,"N"],\
    ["line 2",10,40,90,"N"],["line 3",10,35,120,"N-1"]],\
    columns=["element","var 1","var 2","var 3","regime"])
df2["regime_encoded"] = df2["regime"].apply(format) * max(df2[["var 1","var 2","var 3"]].max(axis=1))

parallel_coordinates(df2[['element', 'var 1', 'var 2', 'var 3', 'regime_encoded']],"element")
ax = plt.gca()
for i,(label,val) in df2.ix[:,['regime','regime_encoded']].drop_duplicates().iterrows():
    ax.annotate(label, xy=(3,val), ha='left', va='center')

plt.show()

这将最终显示以下图表:

平行坐标图的结果

于 2017-07-13T19:46:33.860 回答