SSM*_*SMK 5 python dataframe melt python-3.x pandas
我有一个数据框,可以从下面给出的代码生成
df = pd.DataFrame({'person_id' :[1,2,3],'date1':
['12/31/2007','11/25/2009','10/06/2005'],'val1':
[2,4,6],'date2': ['12/31/2017','11/25/2019','10/06/2015'],'val2':[1,3,5],'date3':
['12/31/2027','11/25/2029','10/06/2025'],'val3':[7,9,11]})
Run Code Online (Sandbox Code Playgroud)
我按照下面的解决方案将其从宽转换为长
pd.wide_to_long(df, stubnames=['date', 'val'], i='person_id',
j='grp').sort_index(level=0)
Run Code Online (Sandbox Code Playgroud)
虽然这适用于如下所示的示例数据,但它不适用于我的超过 200 列的真实数据。我的真实数据不是 person_id,而是 subject_ID,它是 DC0001、DC0002 等值。“I”总是必须是数字吗?相反,它将存根值添加为我的数据集中的新列,并且行数为零
这就是我真正的专栏的样子
我的真实数据可能也包含 NA。那么我是否必须用 Wide_to_long 的默认值填充它们才能工作?
您能帮忙看看可能是什么问题吗?或者任何其他达到相同结果的方法也是有帮助的。
问题在于您的列名称,用于从宽转换为长的数字需要位于列名称的末尾,或者您需要指定 groupby 的后缀。我认为最简单的解决方案是创建一个接受正则表达式和数据帧的函数。
import pandas as pd
import re
def change_names(df, regex):
# Select one of three column groups
old_cols = df.filter(regex = regex).columns
# Create list of new column names
new_cols = []
for col in old_cols:
# Get the stubname of the original column
stub = ''.join(re.split(r'\d', col))
# Get the time point
num = re.findall(r'\d+', col) # returns a list like ['1']
# Make new column name
new_col = stub + num[0]
new_cols.append(new_col)
# Create dictionary mapping old column names to new column names
dd = {oc: nc for oc, nc in zip(old_cols, new_cols)}
# Rename columns
df.rename(columns = dd, inplace = True)
return df
tdf = pd.DataFrame({'person_id' :[1,2,3],'h1date': ['12/31/2007','11/25/2009','10/06/2005'],'t1val': [2,4,6],'h2date': ['12/31/2017','11/25/2019','10/06/2015'],'t2val':[1,3,5],'h3date': ['12/31/2027','11/25/2029','10/06/2025'],'t3val':[7,9,11]})
# Change date columns
tdf = change_names(tdf, 'date$')
tdf = change_names(tdf, 'val$')
print(tdf)
person_id hdate1 tval1 hdate2 tval2 hdate3 tval3
0 1 12/31/2007 2 12/31/2017 1 12/31/2027 7
1 2 11/25/2009 4 11/25/2019 3 11/25/2029 9
2 3 10/06/2005 6 10/06/2015 5 10/06/2025 11
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2310 次 |
| 最近记录: |