【问题标题】:Retrieve data from pandas dataframe to plot in seaborn从 pandas 数据框中检索数据以在 seaborn 中绘图
【发布时间】:2021-08-03 15:25:08
【问题描述】:

这个问题可能已经被回答了一百万次了;然而,开始使用 pandas 并习惯数据框的工作方式仍然很困难。

因此,如果有人可以提出我的方法的更好版本来从数据框中检索感兴趣的数据,我将非常感激。

我有一个存储分数的数据框,可以通过以下方式进行模拟:

import random
import pandas as pd


columns = ['ID', 'Number', 'Score 1', 'Score 2', 'Score 3', 'Score 4']
df = pd.DataFrame(columns=columns)

for k in range(100):
    idx = random.choice([10, 11, 12, 13, 14])
    number = random.choice([1, 2, 3, 4])
    scores = [random.choice(range(1000)) for _ in range (4)]
    entry = pd.DataFrame([[idx, number] + scores], columns=df.columns)
    df = df.append(entry)

诀窍在于,对于给定的 ID,给定的数字 N 可以出现 X 次,其中 X 是非常数。但是,对于数据框中的每一行,分数的数量是固定的,即在本例中为 4。

我想为给定 ID 选择分数 4 并按数字分组。例如

# Retrieve scores of ID 10
id_scores = df.loc[df['ID'] == 10]
numbers = id_scores.Number.unique()

data = list()
for n in numbers:
    data.append(id_scores.loc[id_scores['Number'] == n]['Score 4'].values)

上面的代码有效.. 但我不需要精通 pandas 就可以理解这不是正确的方法。然后,我的目标是用箱线图绘制给定数字(x 轴)的得分 4。因此,每个框可能不包含相同数量的分数,因为给定 ID 的值数不固定。

【问题讨论】:

    标签: python python-3.x pandas pandas-groupby


    【解决方案1】:

    您可以为此使用 pandas groupby:

    df.loc[df['ID'] ==10].groupby('Number')['Score 4'].apply(list)
    

    给出(例如):

    Number
    1     [528, 501, 69, 251, 387]
    2              [549, 321, 302]
    3    [409, 720, 629, 699, 803]
    4    [524, 228, 682, 852, 525]
    Name: Score 4, dtype: object
    

    如果这回答了您的问题,请告诉我。

    【讨论】:

      【解决方案2】:

      你在这里做的是一个典型的SAC模式

      但首先,关于您的 df 创建的性能优化的一点建议:

      # I would use np.random to avoid any explicit looping with *100 func calls
      # (np.random is vectorized)
      
      import numpy as np
      import pandas as pd
      
      idx = np.random.randint(10, 15, 100)
      number = np.random.randint(0, 5, 100)
      scores = np.random.randint(0, 1000, (4, 100))  # 2D array of shape (4, 100)
      columns = ['ID', 'Number', 'Score 1', 'Score 2', 'Score 3', 'Score 4']
      
      # create dataframe from series representing columns and transpose it 
      # idx will be the df index to allow for fast df.loc[ID] indexing instead of
      # using bool mask (e.g. df[df["ID"] == 10])
      df = pd.DataFrame([number, *scores], index=columns, columns=idx).T
      

      现在您可以获取特定 ID 的匹配行并按 Number 对它们进行分组,同时将 Score 4 值作为您偏好的序列返回

      df.loc[10].groupby("Number")["Score 4"].apply(tuple)
      

      如果您更喜欢 Py 原生数据结构,您甚至可以链接 .to_dict()

      【讨论】:

        【解决方案3】:

        上面的答案确实产生了与我的循环代码类似的输出,但实际上两者都不是 seaborn 的正确格式。所以以防万一,这里有一种不同的方法:

        df = pd.read_csv(csv)
        df = df.loc[df['ID'] == 10]
        df = pd.melt(
            df, id_vars='Number', value_vars='Score 4',
            var_name='Score ID', value_name='Score')
        

        然后可以与 seaborn 一起使用:

        sns.boxplot(x='Number', y='Score', hue='Score ID', data=df)
        

        【讨论】:

          猜你喜欢
          • 2014-06-03
          • 2022-06-22
          • 1970-01-01
          • 2017-02-21
          • 2020-04-24
          • 1970-01-01
          • 2015-09-27
          • 2018-10-05
          • 2017-08-10
          相关资源
          最近更新 更多