我有一个55049行667列的数据帧.

数据帧 struct 示例如下:


data = {
    'g1': [1],
    'g2': [2],
    'g3': [3],
    
    'st1_1': [1],
    'st1_2': [1],
    'st1_3': [1],
    'st1_4': [1],
    'st1_5': [5],
    'st1_6': [5],
    'st1_7': [5],
    'st1_8': [5],
    
    'st1_Next_1': [8],
    'st1_Next_2': [8],
    'st1_Next_3': [8],
    'st1_Next_4': [8],
    'st1_Next_5': [9],
    'st1_Next_6': [9],
    'st1_Next_7': [9],
    'st1_Next_8': [9],
    
    'st2_1': [2],
    'st2_2': [2],
    'st2_3': [2],
    'st2_4': [2],
    'st2_5': [2],
    'st2_6': [2],
    'st2_7': [2],
    'st2_8': [2],
    
    'ft_1': [1],
    'ft_2': [0],
    'ft_3': [1],
    'ft_4': [1],
    'ft_5': [1],
    'ft_6': [0],
    'ft_7': [0],
    'ft_8': [1]
}

df = pd.DataFrame(data)
print(df)

为了获得所需的输出,我在使用pd.wide_to_long的地方使用了以下代码

ilist = ['g1','g2','g3']
stublist = ['st1','st1_Next','st2','ft']

df_long = pd.wide_to_long(
      df.reset_index(),
      i=['index']+ilist ,
      stubnames= stublist,
      j='j', sep='_').reset_index()

df_long = df_long[df_long['ft']==1]

上面的代码运行良好,达到了预期效果.

我做了这个宽到长的操作来应用过滤器df_long[df_long['ft']==1].这意味着FT_1需要申请ALL_1,FT_2需要申请ALL_2.....,所以需要申请ALL_8.

问题是执行宽到长的操作大约花了2分钟,因为我有800多个源文件来处理整个过程花费了1600分钟,这是相当高的.

我正在寻找任何替代建议,以换位的数据.

我试了this次,但不太有效,差别很大.

正如@sammywemmy建议的那样,我try 了以下代码.但yields 还不到st1_Next.


ilist = ['g1','g2','g3']
stublist = ['st1','st1_Next','st2','ft']


df_pvot = df.pivot_longer(index=ilist,names_to=stublist,names_pattern=stublist)
print(df_pvot)

输出缺少st1_Next,并且使用st1代替新列的数据库.

Output:

    g1  g2  g3  st1  st2   ft
0    1   2   3    1  2.0  1.0
1    1   2   3    1  2.0  0.0
2    1   2   3    1  2.0  1.0
3    1   2   3    1  2.0  1.0
4    1   2   3    5  2.0  1.0
5    1   2   3    5  2.0  0.0
6    1   2   3    5  2.0  0.0
7    1   2   3    5  2.0  1.0
8    1   2   3    8  NaN  NaN
9    1   2   3    8  NaN  NaN
10   1   2   3    8  NaN  NaN
11   1   2   3    8  NaN  NaN
12   1   2   3    9  NaN  NaN
13   1   2   3    9  NaN  NaN
14   1   2   3    9  NaN  NaN
15   1   2   3    9  NaN  NaN

推荐答案

一种 Select 是使用pivot_longer,将新的标头名称传递给names_to,并将正则表达式列表传递给names_pattern:

# pip install pyjanitor
import pandas as pd

df.pivot_longer(index=ilist,names_to=stublist,names_pattern=stublist)
   g1  g2  g3  st1  st2  ft
0   1   2   3    1    2   1
1   1   2   3    1    2   0
2   1   2   3    1    2   1
3   1   2   3    1    2   1
4   1   2   3    1    2   1
5   1   2   3    1    2   0
6   1   2   3    1    2   0
7   1   2   3    1    2   1

另一种 Select 是调整列的形状,然后是pd.STACK:

reshaped = df.set_index(ilist)
reshaped.columns = reshaped.columns.str.split('_',expand=True).set_names([None,'drop'])
reshaped.stack(level='drop').droplevel('drop').reset_index()
   g1  g2  g3  st1  st2  ft
0   1   2   3    1    2   1
1   1   2   3    1    2   0
2   1   2   3    1    2   1
3   1   2   3    1    2   1
4   1   2   3    1    2   1
5   1   2   3    1    2   0
6   1   2   3    1    2   0
7   1   2   3    1    2   1

这是对更新后的问题的回答--names_pattern依赖于正则表达式,在幕后,pd.Series.str.containsnp.select用于提取列并将其与正则表达式配对.因此,必须正确构建正则表达式以与列匹配:

# pip install pyjanitor
import pandas as pd
import janitor 

# note the inclusion of digits within the regexes
names_pattern = [r'st1_\d+',r'st1_Next',r'st2_\d+', 'ft']

df.pivot_longer(index=ilist,names_to=stublist,names_pattern=names_pattern)
   g1  g2  g3  st1  st1_Next  st2  ft
0   1   2   3    1         8    2   1
1   1   2   3    1         8    2   0
2   1   2   3    1         8    2   1
3   1   2   3    1         8    2   1
4   1   2   3    5         9    2   1
5   1   2   3    5         9    2   0
6   1   2   3    5         9    2   0
7   1   2   3    5         9    2   1

您可以使用stack进行复制,这次使用pd.Series.str.rsplit(),使用n=1.

reshaped = df.set_index(ilist)
reshaped.columns = (reshaped
                    .columns
                    .str
                    .rsplit('_',n=1,expand=True)
                    .set_names([None, 'drop'])
                   )

reshaped.stack(level='drop').droplevel('drop').reset_index()
   g1  g2  g3  st1  st1_Next  st2  ft
0   1   2   3    1         8    2   1
1   1   2   3    1         8    2   0
2   1   2   3    1         8    2   1
3   1   2   3    1         8    2   1
4   1   2   3    5         9    2   1
5   1   2   3    5         9    2   0
6   1   2   3    5         9    2   0
7   1   2   3    5         9    2   1

只要您了解列的模式,并使代码适应它们,就应该没问题.

Python相关问答推荐

运行回文查找器代码时发生错误:[类型错误:builtin_index_or_system对象不可订阅]

如何删除索引过go 的lexsort深度可能会影响性能?' &>

对于一个给定的数字,找出一个整数的最小和最大可能的和

我如何使法国在 map 中完全透明的代码?

Python,Fitting into a System of Equations

Python+线程\TrocessPoolExecutor

迭代嵌套字典的值

Odoo 16使用NTFS使字段只读

在ubuntu上安装dlib时出错

pandas:对多级列框架的列进行排序/重新排序

(Python/Pandas)基于列中非缺失值的子集DataFrame

找到相对于列表索引的当前最大值列表""

有没有办法在不先将文件写入内存的情况下做到这一点?

替换包含Python DataFrame中的值的<;

如何关联来自两个Pandas DataFrame列的列表项?

为什么按下按钮后屏幕的 colored颜色 保持不变?

对于数组中的所有元素,Pandas SELECT行都具有值

查找数据帧的给定列中是否存在特定值

两个名称相同但值不同的 Select 都会产生相同的值(discord.py)

按最大属性值Django对对象进行排序