[英]Reshaping pandas DataFrame Python 3.x
我有一只像这样的熊猫:
df =
cid pid purl tid turl sid surl
c1 p1 urlp1 t1 urlt1 s1 urls1
c1 p1 urlp1 t1 urlt1 s2 urls2
c1 p1 urlp1 t1 urlt1 s3 urls3
c2 p2 urlp2 t2 urlt2 s5 urls5
c2 p2 urlp2 t2 urlt2 s6 urls6
我想要的是这样的结果:
cid uid url
c1 p1 urlp1
c1 t1 urlt1
c1 s1 urls1
c1 s2 urls2
c1 s3 urls3
c2 p2 urlp2
c2 t2 urlt2
c2 s5 urls5
c2 s6 urls6
我尝试使用pd.melt
来实现这一点,但我只能像这样部分地做到这一点:
df2 = pd.melt(df, id_vars = 'cid', value_vars = ['pid','tid','purl'], value_name = 'userid')
如何获得更多的列? 我需要更多列value_name
吗? 我怎样才能做到这一点?
一种手动解决方案是使用列表理解。 步骤是:
cid
。 concat
与数据框列表一起使用,并通过pipe
重命名列[如果需要,添加其他格式]。 reset_index
(将索引提升为一系列)和drop_duplicates
。 这是一个演示:
df = df.set_index('cid')
def formatter(df):
df.columns = ['uid', 'url']
return df
n = int(len(df.columns) / 2)
L = [df.iloc[:, 2*i:2*(i+1)].pipe(formatter) for i in range(n)]
res = pd.concat(L, axis=0).reset_index().drop_duplicates()
print(res)
cid uid url
0 c1 p1 urlp1
3 c2 p2 urlp2
5 c1 t1 urlt1
8 c2 t2 urlt2
10 c1 s1 urls1
11 c1 s2 urls2
12 c1 s3 urls3
13 c2 s5 urls5
14 c2 s6 urls6
不确定这是最简单的方法,但这是我能想到的:
import pandas as pd
from io import StringIO
s = """cid pid purl tid turl sid surl
c1 p1 urlp1 t1 urlt1 s1 urls1
c1 p1 urlp1 t1 urlt1 s2 urls2
c1 p1 urlp1 t1 urlt1 s3 urls3
c2 p2 urlp2 t2 urlt2 s5 urls5
c2 p2 urlp2 t2 urlt2 s6 urls6"""
df = pd.read_table(StringIO(s), sep='\\s+', header=0)
df2 = df.set_index('cid')
df3 = pd.concat([df2[['pid', 'purl']].rename(columns={'pid': 'uid', 'purl': 'url'}),
df2[['tid', 'turl']].rename(columns={'tid': 'uid', 'turl': 'url'}),
df2[['sid', 'surl']].rename(columns={'sid': 'uid', 'surl': 'url'})],
axis=0)
result = df3.drop_duplicates().sort_index().reset_index()
print(result)
输出:
cid uid url
0 c1 p1 urlp1
1 c1 t1 urlt1
2 c1 s1 urls1
3 c1 s2 urls2
4 c1 s3 urls3
5 c2 p2 urlp2
6 c2 t2 urlt2
7 c2 s5 urls5
8 c2 s6 urls6
这些列有一个模式 -> 有些以id
结尾,有些以url
结尾。
我们可以使用这种模式来重塑数据,并删除重复项。
这只是一个替代方案,并且依赖pyjanitor的pivot_longer来帮助重塑过程:
# pip install pyjanitor
import pandas as pd
import janitor as jn
(df.pivot_longer(index = 'cid',
names_to = ('uid', 'url'),
names_pattern = (r".+id", r".+url"),
sort_by_appearance = True)
.drop_duplicates(ignore_index = True)
)
cid uid url
0 c1 p1 urlp1
1 c1 t1 urlt1
2 c1 s1 urls1
3 c1 s2 urls2
4 c1 s3 urls3
5 c2 p2 urlp2
6 c2 t2 urlt2
7 c2 s5 urls5
8 c2 s6 urls6
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.