Python Pandas 中的从长到宽类似于 IBM SPSS 数据将案例重组为变量

问题描述 投票:0回答:1

我想要重新排列数据集中的相关案例组,以便由数字和非数字数据组成的数据在结果数据框中表示为单个案例。本质上,随着时间的推移,我对同一对象进行了多次测量,因此我的数据集中存在重复的 ID 号。此外,无需聚合重组数据。

在 SPSS 中,我将使用以下代码(链接到 SPSS 函数)

CASESTOVARS  
  /ID=PropertyLocation
  /GROUPBY=INDEX.

结果将类似于下图,其中与每个案例关联的变量已添加为新变量,并且变量名称中包含计数(例如案例 1 的“日期”变量是“日期”。“date.1” ' 用于在案例 1 的稍后时间执行的第二次观察)。

在Python中,我尝试使用df.pivot_table,但它聚合我的数值而不显示我的非数字数据。

我的Python代码如下:

reshaped_sales = sales_data_cleansed_2.pivot_table(index="Property Location", columns="sales_index")

“sales_index”列只是每个案例的每个重复测量的计数。并非所有情况都会重复测量相同次数。

这是示例数据集https://drive.google.com/file/d/1Q56bVaLCxfY5jF1C0vhVEmpMtyq7dQif/view?usp=sharing

预先感谢您的帮助!

python pandas pivot
1个回答
0
投票

经过大量搜索和测试,这是一个适用于最小 DataFrame 的解决方案。如果您仍然需要这个答案,您应该能够将这些概念应用到您的大型 DataFrame 中!

### Python code to mimic SPSS's "CASESTOVARS /ID=ProjectID /GROUPBY=INDEX."
import pandas as pd

### Long DataFrame recording dates of changes to insurance:
df = pd.DataFrame({
    ### ID variables to group by:
    'ProjectID': pd.Series([11, 22, 33, 11, 22, 33, 33, 22, 33]).astype('string')
    ,'id_fam': pd.Series(['Blue', 'Green', 'Yellow','Blue', 'Green', 'Yellow', 'Yellow', 'Green', 'Yellow']).astype('string')
    ,'id_kid': pd.Series(['John', 'Jill', 'Jack', 'John', 'Jill', 'Jack', 'Jack', 'Jill', 'Jack']).astype('string')
    ### Variable that should always be the same for each grouping:
    ,'Funding': pd.Series(['Type1', 'Type1', 'Type2', 'Type1', 'Type1', 'Type2', 'Type2', 'Type1', 'Type2']).astype('string')
    ### Variables that change for each grouping:
    ,'InsStatus': pd.Series(['A', 'B', 'C', 'D','A', 'B', 'A', 'C', 'C']).astype('string')
    ,'InsDateChecked': pd.date_range('2018-01-01', periods=9, freq='d')
})

### Sorting by IDs and Date:
df = df.sort_values(by=['ProjectID', 'id_fam', 'id_kid', 'InsDateChecked'], na_position='first', ignore_index=True)

### Pivot the DataFrame:
df_pivoted = df.pivot_table(
    index=['ProjectID', 'id_fam', 'id_kid', 'Funding'] ### All columns that do not change (if not listed will be deleted).
    ,columns=df.groupby(['ProjectID', 'id_fam', 'id_kid']).cumcount() + 1 ### Cumulative count of rows within groupings so groups of data stack vertically. DF should be sorted beforehand. 
    ,values=['InsStatus', 'InsDateChecked'] ### Columns that change.
    ,aggfunc='first' ### To use the values themselves and not an aggregation.
)

### Reorder exploded columns (while all other columns still in the row index & while column names still a MultiIndex):
df_pivoted = df_pivoted.sort_index(axis=1, level=0, ascending=False).sort_index(axis=1, level=1, sort_remaining=False) 
df_pivoted

### Flatten the column MultiIndex & rename columns in the style of SPSS:
df_pivoted.columns = [f'{col[0]}.{col[1]}' for col in df_pivoted.columns]

### Reset row & column indices:
df_pivoted.reset_index(inplace=True)

print(df)
print('\n')
print(df_pivoted)
© www.soinside.com 2019 - 2024. All rights reserved.