176、Python实现长型数据与宽型数据转换
2019-07-10 本文已影响23人
陈容喜
-
背景
在实际工作中为了进行数据展示或者建模,常常需要对长型数据与宽型数据进行转换 1.png
在Excel中很难实现类似的功能,这里主要介绍python实现过程。
1.1什么是长型数据?
1.2什么是宽型数据?
-
python实现长型数据转宽型数据
4.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