带有多维数据框的熊猫+季节性刻面

时间:2018-09-06 09:17:35

标签: python pandas seaborn facet

在Python pandas中,我需要从多维DataFrame进行多面网格处理。 在ab列中,我持有表示实验条件的标量值。 在列xy中,我有两个numpy数组。 x列是数据的x轴,y列是与f(x)对应的函数的值。 显然,xy具有相同数量的元素。

我现在想做一个方面网格,其中行和列指定条件,并在网格的每个单元格中绘制D列与D列的值。

这可能是一个最小的工作示例:

import pandas as pd
d = [0]*4 # initialize a list with 4 elements
d[0] = {'x':[1,2,3],'y':[4,5,6],'a':1,'b':2} # then fill these elements
d[1] = {'x':[3,1,5],'y':[6,5,1],'a':0,'b':3}
d[2] = {'x':[3,1,5],'y':[6,5,1],'a':1,'b':3}
d[3] = {'x':[3,1,5],'y':[6,5,1],'a':0,'b':2}
pd.DataFrame(d) # create the pandas dataframe

如何使用已有的构面功能来解决按条件y vs xa分组的b绘制问题?

由于我需要将此函数应用于具有不同列名的常规数据集,因此我想避免求助于硬编码的解决方案,而是想知道是否有可能将seaborn FacetGrid函数扩展到此类问题

3 个答案:

答案 0 :(得分:2)

我认为最好的方法是先拆分嵌套数组,然后创建带有Seaborn的构面网格。

感谢这篇文章(Split nested array values from Pandas Dataframe cell over multiple rows),我能够在您的数据框中拆分嵌套数组:

unnested_lst = []
for col in df.columns:
    unnested_lst.append(df[col].apply(pd.Series).stack())
result = pd.concat(unnested_lst, axis=1, keys=df.columns).fillna(method='ffill')

然后您可以使用以下代码制作构面网格:

import seaborn as sbn
fg = sbn.FacetGrid(result, row='b', col='a')
fg.map(plt.scatter, "x", "y", color='blue')

答案 1 :(得分:1)

您需要一个长框才能使用FacetGrid,所以最好的选择是分解列表,然后重新组合并应用:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

d = [0]*4
d[0] = {'x':[1,2,3],'y':[4,5,6],'a':1,'b':2} # then fill these elements
d[1] = {'x':[3,1,5],'y':[6,5,1],'a':0,'b':3}
d[2] = {'x':[3,1,5],'y':[6,5,1],'a':1,'b':3}
d[3] = {'x':[3,1,5],'y':[6,5,1],'a':0,'b':2}
df = pd.DataFrame(d)

df.set_index(['a','b'], inplace=True, drop=True)

x_long = pd.melt(df['x'].apply(pd.Series).reset_index(),
                 id_vars=['a', 'b'], value_name='x')

y_long = pd.melt(df['y'].apply(pd.Series).reset_index(),
                 id_vars=['a', 'b'], value_name='y')

long_df = pd.merge(x_long, y_long).drop('variable', axis='columns')

grid = sns.FacetGrid(long_df, row='a', col='b')
grid.map(plt.scatter, 'x', 'y')
plt.show()

这将向您显示以下内容: enter image description here

答案 2 :(得分:0)

我认为最好,最短和最易理解的解决方案是定义一个适当创建的lambda函数。它以FacetGrid.map方法指定的映射变量作为输入,并以.values[0]的numpy数组形式获取其值,因为它们是唯一的。

import pandas as pd
d = [0]*4 # initialize a list with 4 elements
d[0] = {'x':[1,2,3],'y':[4,5,6],'a':1,'b':2} # then fill these elements
d[1] = {'x':[3,1,5],'y':[6,5,1],'a':0,'b':3}
d[2] = {'x':[3,1,5],'y':[6,5,1],'a':1,'b':3}
d[3] = {'x':[3,1,5],'y':[6,5,1],'a':0,'b':2}
df = pd.DataFrame(d) # create the pandas dataframe

import seaborn as sns
import matplotlib.pyplot as plt
grid = sns.FacetGrid(df,row='a',col='b')
grid.map(lambda _x,_y,**kwargs : plt.scatter(_x.values[0],_y.values[0]),'x','y')

seaborn faceting with lambda functions