今天在工作中遇到要将pandas数据框的一行拆成多行,和一列拆为多列的需求,一台服务器中可以有多个网卡,每个网卡都有状态,通过网卡的上下行流量。下面以一组“数据”为例,来说一下pandas如何将一行拆分为多行,一列拆分为多列。
需求如下图
思路:
1.先将(0,c)拆成一个数据框
2.再将新数据框拆成4列(list1,list2,list3,list4)
3. 将原始数据框的c列删除,合并两个数据框
import numpy
import pandas as pd
from tabulate import tabulate
dict1 = {"a": ["test1", "test2"], "b": ["up", "up"],
"c": ["eth1|up|16G|32G\neth2|up|null|32G\neth3|up|null|32G", "eth0|up|32G|32G"]}
df1 = pd.DataFrame(dict1)
print(tabulate(df1, headers='keys', tablefmt='fancy_grid'))
上述代码中tabulate模块能够对二维数据进行表格输出,可以把列表进行表格格式化
逐步实现:
1.先将(0,c)拆成一个数据框
将字符串按换行符分割
df_2 = df1['c'].str.split('\n',expand=True)
df_2
把行转为列
df_2 = df_2.stack()
df_2
重置索引,将二级索引变为一级索引
df_2 = df_2.reset_index(level=1, drop=True)
df_2
2.再将新数据框拆成4列(list1,list2,list3,list4)
将数据以“|”为分隔符拆为4列
df_2 = df_2.str.split('|', expand=True)
df_2
改索引名称
df_2.columns = ["list1", "list2", "list3", "list4"]
df_2
3. 将原始数据框的c列删除,合并两个数据框
先将原始数据框的c列删除,再跟新数据框合并
df_new = df1.drop("c", axis=1).join(df_2)
df_new
格式化输出
print(tabulate(df_new, headers='keys', tablefmt='fancy_grid'))
一行代码实现:
df_test = df1.drop("c", axis=1).join(df1['c'].str.split('\n',expand=True).stack().reset_index(level=1, drop=True).str.split('|', expand=True))
print(tabulate(df_test, headers='keys', tablefmt='fancy_grid'))
(需要单独改一下索引名)
源码:
# !/usr/bin/env python
# -*- coding: UTF-8 -*-
import numpy
import pandas as pd
from tabulate import tabulate
dict1 = {"a": ["test1", "test2"], "b": ["up", "up"],
"c": ["eth1|up|16G|32G\neth2|up|null|32G\neth3|up|null|32G", "eth0|up|32G|32G"]}
df1 = pd.DataFrame(dict1)
print(tabulate(df1, headers='keys', tablefmt='fancy_grid'))
# 一行拆为多行
df_2 = df1['c'].str.split('\n',expand=True).stack().reset_index(level=1, drop=True)
# 一列拆多列
df_sp = df_2.str.split('|', expand=True)
# 改列名
df_sp.columns = ["list1", "list2", "list3", "list4"]
# 删除c列,合并数据框
df_new = df1.drop("c", axis=1).join(df_sp)
print(tabulate(df_new, headers='keys', tablefmt='fancy_grid'))
###########################################################
# 一步实现 一行拆为多行一列拆多列
df_test = df1.drop("c", axis=1).join(df1['c'].str.split('\n',expand=True).stack().reset_index(level=1, drop=True).str.split('|', expand=True))
print(tabulate(df_test, headers='keys', tablefmt='fancy_grid'))