【问题标题】:Create a 2D plot pixel grid based on a pandas series of lists基于 pandas 系列列表创建 2D 绘图像素网格
【发布时间】:2017-01-30 10:47:21
【问题描述】:

假设我们有一个 pandas 系列列表,其中每个列表都包含一些描述为字符串的特征,如下所示:

0  ["A", "C", "G", ...]
1  ["B", "C", "H", ...]
2  ["A", "X"]
...
N  ["J", "K", ...]

绘制 2D 像素网格的最佳/最简单方法是什么?其中 X 轴是特征的出现,Y 轴是系列 0、1、2、...、N 中的每个样本?

9 月 22 日 16 日编辑:

似乎我没有明确提到特征列表对于所有观察结果不一定具有相同的大小。观察 1 可以有 4 个特征,观察 2 可以没有一个,观察 3 可以有 5 个,依此类推。因此,如果不对它们进行预处理以填充缺失的特征,我就无法立即将它们转换为 numpy 数组。

【问题讨论】:

  • 你有没有想过将其转换为 Numpy 矩阵,然后使用 matplotlib 来做你想做的事?请在问题中也包括您解决问题的方法。
  • 这里有点像在黑暗中拍摄,但您是否在寻找2D "pixel grid" like this?如果不是,请详细说明您想要什么,对我来说,将 2D 绘图作为轴之一并没有多大意义。
  • 我认为真正的问题是首先将列表列表中的特征转换为一种矩阵。请注意,系列中的观察值不一定相同。它类似于pandas.get_dummies(),但此方法基于单列的标量值提取矩阵,而不是单列中列表中的值。
  • matplotlib mapshow 是我想要的。

标签: python pandas matplotlib plot series


【解决方案1】:

由于我已经在评论中编写了图像的代码,并且 Ed 似乎对您的问题有相同的解释,所以我将继续添加我的解决方案。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import string

M, N = 100, 10
letters = list(string.ascii_uppercase)
data = np.random.choice(letters, (M, N))

df = pd.DataFrame(data)
# Get frequency of letters in each column using pd.value_counts
df_freq = df.apply(pd.value_counts).T

# Plot frequency dataframe with seaborn heatmap
ax = sns.heatmap(df_freq, linewidths=0.1, annot=False, cbar=True)
plt.show()

【讨论】:

  • 快到了。正如我在编辑问题后解释的那样,我事先没有完美的 MxN 矩阵,具有 M 个观察值和 N 个特征。我有一个 M 个观察的列表,其中每个观察都有一个最多 N 个特征的列表。
  • 我想出了如何使用CountVectorizer 特征提取sklearn 转换M 个观察值列表,其中每个观察值是一个最多M 个特征的列表。完成后,此答案将解决此问题。
  • 太好了,很高兴它对你有用!请记住,如果您必须添加到我的答案中,您可以考虑添加自己的答案。
  • 这是一个更好的答案,我感觉会有一个 pandas 函数来做......
【解决方案2】:

将 pandas 用于一维直方图似乎很简单,如 this 答案。你可以使用这个想法,用 26 填充一个 N 数组,然后用

绘制 2D
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import random
import string
from collections import Counter

#Generate list of letters and dataframe
N = 20
M = 1000
letterlist = []
for i in range(N):
    letterlist.append([random.choice(string.ascii_uppercase) for i in range(M)])
df = pd.DataFrame(letterlist)

#Fill an array of size N by 26
im = np.zeros([N,26])
for n in range(N):
    #Get histogram of letters for a line as Dict
    letter_counts = Counter(df.loc[n])
    #Add to array
    for k in letter_counts.keys():
        c = ord(k.lower()) - 97
        im[n,c] = letter_counts[k]

#Plot
plt.imshow(im, interpolation='none')
plt.colorbar()
plt.axis('tight')
plt.xticks(range(26), [i for i in string.ascii_uppercase])
plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2019-04-22
    • 1970-01-01
    • 2012-11-03
    • 2019-07-03
    • 2016-11-24
    相关资源
    最近更新 更多