Python 数据帧从窄到宽,透视表无聚合

Python 数据帧从窄到宽,透视表无聚合,python,pandas,Python,Pandas,我有一个包含iris数据集的熊猫数据帧。我想将此数据框子集为仅包括萼片长度和物种,然后对其进行重塑,使列为物种的唯一值,值为该物种的值 # load data into a dataframe df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv') head(df) +----+---------------+--------------+---------------

我有一个包含
iris
数据集的熊猫数据帧。我想将此数据框子集为仅包括
萼片长度
物种
,然后对其进行重塑,使列为
物种
的唯一值,值为该物种的值

# load data into a dataframe
df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')

head(df)
+----+---------------+--------------+---------------+--------------+---------+
|    | sepal_length  | sepal_width  | petal_length  | petal_width  | species |
+----+---------------+--------------+---------------+--------------+---------+
| 0  |          5.1  |         3.5  |          1.4  |         0.2  | setosa  |
| 1  |          4.9  |         3.0  |          1.4  |         0.2  | setosa  |
| 2  |          4.7  |         3.2  |          1.3  |         0.2  | setosa  |
| 3  |          4.6  |         3.1  |          1.5  |         0.2  | setosa  |
| 4  |          5.0  |         3.6  |          1.4  |         0.2  | setosa  |
+----+---------------+--------------+---------------+--------------+---------+
我能做的是,我从熊猫身上取下数据,用字典重塑数据,但我不知道如何在熊猫身上做

data = df.to_dict('records')

e = {}
for line in data:
    e[line['species']] = []

for line in data:
    e[line['species']].append(line['sepal_length'])

new = pd.DataFrame(e)
这就是我想要的结局:

+----+---------+-------------+-----------+
|    | setosa  | versicolor  | virginica |
+----+---------+-------------+-----------+
| 0  |    5.1  |        7.0  |       6.3 |
| 1  |    4.9  |        6.4  |       5.8 |
| 2  |    4.7  |        6.9  |       7.1 |
| 3  |    4.6  |        5.5  |       6.3 |
| 4  |    5.0  |        6.5  |       6.5 |
+----+---------+-------------+-----------+
我试过使用
pd.crosstab(df['sepal\u length',df['species'))
但这并不能满足我的需求。我也尝试过使用
df.pivot\u表('sepal\u length',columns='species')
,但也不是这样


我错过了什么

您要做的事情需要采取一些步骤。(以下代码假定使用本标准)

  • 首先,让我们仅按所需的列对数据帧进行子集划分

    df_subset = df[['sepal_length','species']]
    
  • 接下来,使用(
    pandas.pivot_table
    )的intead将数据帧从“长”转换为“平”

  • 现在,我们已经接近您想要的了,但是因为您的三个
    species
    列沿着相同的索引运行,所以对于任何给定行,数据透视
    DataFrame
    为三列中的两列返回
    NaN
    s。我们可以通过按列连接
    数据帧
    来解决这个问题,同时对其重新编制索引。(基本上是创建三个数据框架,每个物种一个,并通过一个新的索引将它们连接起来)。我们可以采用以下两种方法之一:

    • 紧凑型解决方案:

      names = ['setosa','versicolor','virginica']
      
      df_final = pd.concat(map(lambda name: df_pivot[name].dropna().reset_index().drop('index',axis=1), names), axis=1) 
      
    • 这相当于:

      df_final = pd.concat([
          df_pivot['setosa'].dropna().reset_index().drop('index',axis=1),
          df_pivot['versicolor'].dropna().reset_index().drop('index',axis=1),
          df_pivot['virginica'].dropna().reset_index().drop('index',axis=1)],axis=1)
      
  • IIUC您可以在
    species
    col上使用并设置索引,然后使用不需要
    agg
    func的替代项

    df1 = df.set_index(df.groupby('species').cumcount())
    
    df1 = df1.pivot(columns='species', values='sepal_length').rename_axis(None,axis=1)
    
    print (df1)
    
       setosa  versicolor  virginica
    0     5.1         7.0        6.3
    1     4.9         6.4        5.8
    2     4.7         6.9        7.1
    3     4.6         5.5        6.3
    4     5.0         6.5        6.5
    

    初始数据帧是什么样子的?
    df1 = df.set_index(df.groupby('species').cumcount())
    
    df1 = df1.pivot(columns='species', values='sepal_length').rename_axis(None,axis=1)
    
    print (df1)
    
       setosa  versicolor  virginica
    0     5.1         7.0        6.3
    1     4.9         6.4        5.8
    2     4.7         6.9        7.1
    3     4.6         5.5        6.3
    4     5.0         6.5        6.5