176、Python实现长型数据与宽型数据转换

  1. 背景

    在实际工作中为了进行数据展示或者建模,常常需要对长型数据与宽型数据进行转换
    1.png

在Excel中很难实现类似的功能,这里主要介绍python实现过程。
1.1什么是长型数据?

长数据一般是指数据集中的变量没有做明确的细分,即变量中至少有一个变量中的元素存在值严重重复循环的情况(可以归为几类),表格整体的形状为长方形,数据总体的表现为:变量少而观察值多。例如:
2.png

1.2什么是宽型数据?

宽数据是指数据集对所有的变量进行了明确的细分,各变量的值不存在重复循环的情况也无法归类。数据总体的表现为:变量多而观察值少。例如:
3.png
  1. python实现长型数据转宽型数据


    4.png
5.png
6.png
7.png
8.png
9.png
10.png
11.png
12.png
13.png
14.png
15.png

附代码:

# coding: utf-8

# # Python实现长型数据与宽型数据转换

# ### 方法一
# #### 读取数据

# In[1]:

import pandas as pd
df = pd.read_excel(r'F:\python\notebook\长型数据与宽型数据转换\商品数据.xlsx')
df.head()


# In[2]:

sup_list = []
qty_list = []
price_list = []


# #### 遍历相同商品名称的所有行,并将购买数量、价格梯度以列表形式保存
# unique() 对商品名称去重

# In[3]:

for sup in df['商品名称'].unique():                      
    sup_df = df[df['商品名称']==sup]
    x = ','.join(sup_df['购买数量'].astype(str).tolist()) 
    y = ','.join(sup_df['价格梯度'].astype(str).tolist())
    sup_list.append(sup)
    qty_list.append(x)
    price_list.append(y)


# #### 构建新的数据框

# In[4]:

data = pd.DataFrame({'商品名称':sup_list,'购买数量':qty_list,'价格梯度':price_list})
data.head()


# #### 分列

# In[5]:

qty = data['购买数量'].str.split(',', expand=True).rename(columns={0:'数量1', 1:'数量2', 2:'数量3', 3:'数量4'})
price = data['价格梯度'].str.split(',', expand=True).rename(columns={0:'价格1', 1:'价格2', 2:'价格3', 3:'价格4'}).astype(float).round(2)


# #### 按索引合并

# In[6]:

data = data.merge(qty,how='left',left_index=True,right_index=True).merge(price,how='left',left_index=True,right_index=True)
data.head()


# #### 删除不必要的字段

# In[7]:

data = data.drop(['价格梯度','购买数量'],axis=1)
data


# ### 方法二

# In[8]:

import pandas as pd
df = pd.read_excel(r'F:\python\notebook\长型数据与宽型数据转换\商品数据.xlsx')
df


# #### 增加一列辅助列,根据商品名称分组对购买数量进行排名

# In[9]:

df['rnk'] = df.groupby(['商品名称'])['购买数量'].rank(ascending=1,method='first')
df['rnk'] = df['rnk'].astype(int)
df['rnk'] = df['rnk'].astype(str)
df


# #### 插入两列,根据购买数量和价格梯度添加标签

# In[10]:

df['数量标签'] = '数量'
df['数量标签'] = df['数量标签'].str.cat(df['rnk'])
df['价格标签'] = '价格'
df['价格标签'] = df['价格标签'].str.cat(df['rnk'])
df


# #### 对购买数量和价格梯度使用pivot_table(透视表)

# In[11]:

da=df.pivot_table(index=['商品名称'],columns=['数量标签'],values=['购买数量'])
da


# In[12]:

db=df.pivot_table(index=["商品名称"],columns=["价格标签"],values=["价格梯度"])                    
db


# #### 使用merge合并两个透视表(类似SQL的left join用法)

# In[13]:

da = da.merge(db,how='left',left_index=True,right_index=True)
da


# #### 把第一层的列名删除

# In[14]:

da.columns = da.columns.droplevel(0)
da


# #### 重置透视表的索引

# In[15]:

da = da.rename_axis(None, axis=1).reset_index() 
da

推荐阅读更多精彩内容