如何在 pandas DataFrame 上绘制一些包含字符串的列的平行坐标?
How to plot parallel coordinates on pandas DataFrame with some columns containing strings?
我想为 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: invalid literal for float(): N
我想这意味着 parallel_coordinates
函数不接受字符串。
我正在尝试做的事情的例子
我正在尝试做类似这个例子的事情,其中 Race 和 Sex 是字符串而不是数字:
问题
有什么方法可以使用 pandas
parallel_coordinates
来执行这样的图形吗?如果没有,我怎么能尝试这样的图形?也许 matplotlib
?
我必须提到我正在特别寻找 Python 2.5 和 pandas 版本 0.9.0
.
下的解决方案
我不完全清楚您想对 regime
列做什么。
如果问题只是它的存在阻止了绘图显示,那么您可以简单地从绘图中省略有问题的列:
parallel_coordinates(df2, class_column='element', cols=['var 1', 'var 2', 'var 3'])
查看您提供的示例,我了解到您希望分类变量以某种方式放置在垂直线上,并且类别的每个值都由不同的 y 值表示。我做对了吗?
如果我是,那么您需要将您的分类变量(此处为 regime
)转换为数值。为此,我使用了这个技巧 I found on this website.
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')
根据@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()
这将最终显示下图:
我想为 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: invalid literal for float(): N
我想这意味着 parallel_coordinates
函数不接受字符串。
我正在尝试做的事情的例子
我正在尝试做类似这个例子的事情,其中 Race 和 Sex 是字符串而不是数字:
问题
有什么方法可以使用 pandas
parallel_coordinates
来执行这样的图形吗?如果没有,我怎么能尝试这样的图形?也许 matplotlib
?
我必须提到我正在特别寻找 Python 2.5 和 pandas 版本 0.9.0
.
我不完全清楚您想对 regime
列做什么。
如果问题只是它的存在阻止了绘图显示,那么您可以简单地从绘图中省略有问题的列:
parallel_coordinates(df2, class_column='element', cols=['var 1', 'var 2', 'var 3'])
查看您提供的示例,我了解到您希望分类变量以某种方式放置在垂直线上,并且类别的每个值都由不同的 y 值表示。我做对了吗?
如果我是,那么您需要将您的分类变量(此处为 regime
)转换为数值。为此,我使用了这个技巧 I found on this website.
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')
根据@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()
这将最终显示下图: