如何使用 Python 将 CSV 数据从宽格式转置为长数据集
How to transpose CSV data from a wide format to long dataset using Python
我需要使用 Python 对任意数量的 "items" 执行以下数据转换。前两列始终相同,然后可能有数千个 "itemN" 列,我希望所有实数值都在一个新的单列中。
我曾尝试使用 pandas.wide_to_long,但据我所知,我会将新名称放入转置的 table 中,如果项目数量可能发生变化,这将不起作用。
type rid item1 item2 item3
apple [81] 1.1 1.1 1.1
orange [82] 2.2 2.2 2.2
banana [41,42,43,52] 3.3 3.3 3.3
kiwi [90,95] 4.4 4.4 4.4
到
type rid gid value
apple [81] item1 1.1
apple [81] item2 1.1
apple [81] item3 1.1
orange [82] item1 2.2
orange [82] item2 2.2
orange [82] item3 2.2
banana [41,42,43,52] item1 3.3
banana [41,42,43,52] item2 3.3
banana [41,42,43,52] item3 3.3
kiwi [90,95] item1 4.4
kiwi [90,95] item2 4.4
kiwi [90,95] item3 4.4
到目前为止,我已经尝试过对 numpy 数组使用双 for 循环和索引切片并使用 pandas.wide_to_long。
a = np.array([['apple' ,tuple([81]) ,1.1 ,1.1 ,1.1] ,['orange' ,tuple([82]) ,2.2 ,2.2 ,2.2],['banana' ,tuple([41,42,43,52]) ,3.3 ,3.3 ,3.3],['kiwi' ,tuple([90,95]) ,4.4 ,4.4 ,4.4]])
names = ['type' ,'rid' ,'item1' ,'item2' ,'item3']
df = pd.DataFrame(a,columns=names)
这看起来像是 DataFrame.explode
(pandas 0.25+) 的工作。
# Build a DataFrame identical to the first example data you provided
d = {'type': {0: 'apple', 1: 'orange', 2: 'banana', 3: 'kiwi'},
'rid': {0: [81], 1: [82], 2: [41, 42, 43, 52], 3: [90, 95]},
'item1': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4},
'item2': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4},
'item3': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4}})
df = pd.DataFrame(d)
# Explode the 'rid' column and reset to default integer index
df.explode('rid').reset_index(drop=True)
type rid item1 item2 item3
0 apple 81 1.1 1.1 1.1
1 orange 82 2.2 2.2 2.2
2 banana 41 3.3 3.3 3.3
3 banana 42 3.3 3.3 3.3
4 banana 43 3.3 3.3 3.3
5 banana 52 3.3 3.3 3.3
6 kiwi 90 4.4 4.4 4.4
7 kiwi 95 4.4 4.4 4.4
您可以将前 2 列放入索引,堆叠生成的数据框,然后重置索引:
df.set_index(['type', 'rid']).stack().reset_index()
给出:
type rid level_2 0
0 apple [81] item1 1.1
1 apple [81] item2 1.1
2 apple [81] item3 1.1
3 orange [82] item1 2.2
4 orange [82] item2 2.2
5 orange [82] item3 2.2
6 banana [41,42,43,52] item1 3.3
7 banana [41,42,43,52] item2 3.3
8 banana [41,42,43,52] item3 3.3
9 kiwi [90,95] item1 4.4
10 kiwi [90,95] item2 4.4
11 kiwi [90,95] item3 4.4
只需重命名新列即可:
df.set_index(['type', 'rid']).stack().reset_index().rename(columns={'level_2': 'gid',
0: 'value'})
给出预期的数据帧。
简单的答案就是使用 pandas.melt() 函数。
df = df.melt(id_vars=['type', 'rid'], value_vars=['item1', 'item2', 'item3'])
输出:
我需要使用 Python 对任意数量的 "items" 执行以下数据转换。前两列始终相同,然后可能有数千个 "itemN" 列,我希望所有实数值都在一个新的单列中。
我曾尝试使用 pandas.wide_to_long,但据我所知,我会将新名称放入转置的 table 中,如果项目数量可能发生变化,这将不起作用。
type rid item1 item2 item3
apple [81] 1.1 1.1 1.1
orange [82] 2.2 2.2 2.2
banana [41,42,43,52] 3.3 3.3 3.3
kiwi [90,95] 4.4 4.4 4.4
到
type rid gid value
apple [81] item1 1.1
apple [81] item2 1.1
apple [81] item3 1.1
orange [82] item1 2.2
orange [82] item2 2.2
orange [82] item3 2.2
banana [41,42,43,52] item1 3.3
banana [41,42,43,52] item2 3.3
banana [41,42,43,52] item3 3.3
kiwi [90,95] item1 4.4
kiwi [90,95] item2 4.4
kiwi [90,95] item3 4.4
到目前为止,我已经尝试过对 numpy 数组使用双 for 循环和索引切片并使用 pandas.wide_to_long。
a = np.array([['apple' ,tuple([81]) ,1.1 ,1.1 ,1.1] ,['orange' ,tuple([82]) ,2.2 ,2.2 ,2.2],['banana' ,tuple([41,42,43,52]) ,3.3 ,3.3 ,3.3],['kiwi' ,tuple([90,95]) ,4.4 ,4.4 ,4.4]])
names = ['type' ,'rid' ,'item1' ,'item2' ,'item3']
df = pd.DataFrame(a,columns=names)
这看起来像是 DataFrame.explode
(pandas 0.25+) 的工作。
# Build a DataFrame identical to the first example data you provided
d = {'type': {0: 'apple', 1: 'orange', 2: 'banana', 3: 'kiwi'},
'rid': {0: [81], 1: [82], 2: [41, 42, 43, 52], 3: [90, 95]},
'item1': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4},
'item2': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4},
'item3': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4}})
df = pd.DataFrame(d)
# Explode the 'rid' column and reset to default integer index
df.explode('rid').reset_index(drop=True)
type rid item1 item2 item3
0 apple 81 1.1 1.1 1.1
1 orange 82 2.2 2.2 2.2
2 banana 41 3.3 3.3 3.3
3 banana 42 3.3 3.3 3.3
4 banana 43 3.3 3.3 3.3
5 banana 52 3.3 3.3 3.3
6 kiwi 90 4.4 4.4 4.4
7 kiwi 95 4.4 4.4 4.4
您可以将前 2 列放入索引,堆叠生成的数据框,然后重置索引:
df.set_index(['type', 'rid']).stack().reset_index()
给出:
type rid level_2 0
0 apple [81] item1 1.1
1 apple [81] item2 1.1
2 apple [81] item3 1.1
3 orange [82] item1 2.2
4 orange [82] item2 2.2
5 orange [82] item3 2.2
6 banana [41,42,43,52] item1 3.3
7 banana [41,42,43,52] item2 3.3
8 banana [41,42,43,52] item3 3.3
9 kiwi [90,95] item1 4.4
10 kiwi [90,95] item2 4.4
11 kiwi [90,95] item3 4.4
只需重命名新列即可:
df.set_index(['type', 'rid']).stack().reset_index().rename(columns={'level_2': 'gid',
0: 'value'})
给出预期的数据帧。
简单的答案就是使用 pandas.melt() 函数。
df = df.melt(id_vars=['type', 'rid'], value_vars=['item1', 'item2', 'item3'])
输出: