Python Pandas将Series转换为Dataframe,其中包含Series内的列名和值

dzhpxtsq  于 2023-05-12  发布在  Python
关注(0)|答案(3)|浏览(146)

TLDR;遍历 Dataframe 以将列名和值拉入新的 Dataframe
我有一个很长的 Dataframe 格式

0 column 1
1 value
2 column 2
3 value
4 column 3
5 value

对大约100,000行上的32列重复。
我想迭代此数据框以创建一个新的数据框:

Column 1 Column 2 Column 3
Value    Value     Value

我曾尝试转换为字典,以启用键上的匹配,但失败了。

u4dcyp6a

u4dcyp6a1#

由于您有100,000行,因此将存在重复的列名,并且还需要将值分组到行中。您可以提取唯一的列名,然后根据列名的数量将值分块。例如:

df = pd.DataFrame({'col': [
    'column 1', 'value 1', 'column 2', 'value 2', 'column 3', 'value 3',
    'column 1', 'value 4', 'column 2', 'value 5', 'column 3', 'value 6']
})

cols = np.unique(df['col'].iloc[::2])
values = [list(df['col'].iloc[1::2][i:i+len(cols)]) for i in range(0, len(df) // 2, len(cols))]
out = pd.DataFrame(values, columns=cols)

样本输出:

column 1 column 2 column 3
0  value 1  value 2  value 3
1  value 4  value 5  value 6

注意为了示例代码的目的,我选择了一种简单的方法来分块值。为了获得最佳性能,您可能需要使用this Q&A中描述的方法之一。

mnemlml8

mnemlml82#

假设列为“col”,使用简单的切片:

cols = df.loc[df.index[::2], 'col'].to_numpy()
vals = df.loc[df.index[1::2], 'col'].to_numpy()

out = pd.DataFrame([vals], columns=cols)

输出:

column 1 column 2 column 3
0    value    value    value
重复值

考虑另一个示例:

col
0  column 1
1   value 1
2  column 2
3   value 2
4  column 2  # this name already exists
5   value 3

如果您有重复的列名,那么pivot可能有用:

mask = np.arange(len(df))%2 == 0

out = (df[mask]
 .assign(values=df['col'].shift(-1),
         idx=lambda d: d.groupby('col').cumcount()
         )
 .pivot(index='idx', columns='col', values='values')
 .rename_axis(index=None, columns=None)
)

输出:

column 1 column 2
0  value 1  value 2
1      NaN  value 3
使用numpy整形

如果列名总是按照逻辑顺序(1,2,3,...,32,1,2,3,...),那么reshape将是一个很好的选择:

df = pd.DataFrame({'col': [f'{c}{i%32+1}' if c=='column' else f'{c}{i+1}'
                           for i in range(50_000) for c in ['column', 'value']]})

N = 32

a = df['col'].to_numpy()
values = a[1::2]

out = pd.DataFrame(np.pad(values, (0, len(values)-len(values)//N*N),
                          constant_values=np.nan).reshape((-1, N)),
                   columns=a[:2*N:2])
  • 谢谢你@Nick指出这一点 *
bhmjp9jg

bhmjp9jg3#

With 100000 rows there will be some repetition of column names and values will need slicing into multiple lists,那么使用32列可能不是显示数据的正确方法。

Repeating for 32 columns over about 100,000 rows.

I would like to iterate over this data frame to create a new data frame with:

Column 1 Column 2 Column 3
Value    Value     Value
I have tried converting to a dictionary to enable matching on the keys but have failed

也许你可以使用iloc[::2]索引来迭代值,然后使用zip合并列名和值,然后转换为 Dataframe 。
下面是演示代码。

import io
import pandas as pd

df_str = '''
_id  _val
0 column1
1 value
2 column2
3 value
4 column3
5 value
'''
df = pd.read_csv(io.StringIO(df_str.strip()), sep='\s+')
print(df)

# then
dfn = pd.DataFrame(zip(df['_val'].iloc[::2], df['_val'].iloc[1::2]), columns=['col_name', 'value'])
print(dfn)

输出

_id     _val
0    0  column1
1    1    value
2    2  column2
3    3    value
4    4  column3
5    5    value

    col_name    value
0   column1 value
1   column2 value
2   column3 value

相关问题