pandas列值为行值

时间:2017-03-02 07:51:34

标签: python pandas numpy jupyter-notebook jupyter

我有一个数据集(171列),当我把它带入我的数据框时,它看起来像这样 -

javac

现在我想以这种方式更改我的数据框 -

ANO MNO UJ2010  DJ2010   UF2010 DF2010   UM2010 DM2010    UA2010    DA2010 ...
1   A   113   06/01/2010    129 06/02/2010  143 06/03/2010  209 05/04/2010 ...
2   B   218   06/01/2010    211 06/02/2010  244 06/03/2010  348 05/04/2010 ...
3   C   22    06/01/2010    114 06/02/2010  100 06/03/2010  151 05/04/2010 ...

我尝试使用 ANO MNO Time Unit 1 A 06/01/2010 113 1 A 06/02/2010 129 1 A 06/03/2010 143 2 B 06/01/2010 218 2 B 06/02/2010 211 2 B 06/03/2010 244 3 C 06/01/2010 22 3 C 06/02/2010 114 3 C 06/03/2010 100 .... ..... ,但我认为它并没有满足我的目的。

如果有人帮我解决这个问题,那将会很棒:)

3 个答案:

答案 0 :(得分:3)

在过滤要在不同标题下分组的列后,使用pd.lreshape作为pd.melt的替代替代方法。

通过使用pd.lreshape,当您将字典对象注入其groups参数时,键将采用新的标题名称以及作为值的所有列名列表{ {1}}将在该单个标题下投射。因此,它在转换后生成一个长格式dict

最后将DF w.r.t排序在未使用的列中以相应地对齐它们。

然后,最后一个DF通过删除中间索引将索引轴重新标记为默认整数值。

reset_index(drop=True)

enter image description here

如果分组列的长度不匹配,则:

d = pd.lreshape(df, {"Time": df.filter(regex=r'^D').columns, 
                     "Unit": df.filter(regex=r'^U').columns})

d.sort_values(['ANO', 'MNO']).reset_index(drop=True)

如上所述,继续执行与from itertools import groupby, chain unused_cols = ['ANO', 'MNO'] cols = df.columns.difference(unused_cols) # filter based on the common strings starting from the first slice upto end. fnc = lambda x: x[1:] pref1, pref2 = "D", "U" # Obtain groups based on a common interval of slices. groups = [list(g) for n, g in groupby(sorted(cols, key=fnc), key=fnc)] # Fill single length list with it's other char counterpart. fill_missing = [i if len(i)==2 else i + [pref1 + i[0][1:] if i[0][0] == pref2 else pref2 + i[0][1:]] for i in groups] # Reindex based on newly obtained column names. df = df.reindex(columns=unused_cols + list(chain(*fill_missing))) 相同的步骤,但这次包含pd.lreshape参数。

答案 1 :(得分:1)

您可以按stack重新塑造,但首先在MultiIndex%的列中创建//

MultiIndexTimeUnit值映射到MultiIndex的第二级,按//按地板划分(2),差异为%每对由模数除法(stack)创建。

然后//使用由index创建的最后一个级别,并在reset_index(level=2, drop=True)中创建新级别的MultiIndex,这是不必要的,因此会被columns删除。

上次reset_index将第一级和第二级转换为[[1,0]]

df = df.set_index(['ANO','MNO']) cols = np.arange(len(df.columns)) df.columns = [cols % 2, cols // 2] print (df) 0 1 0 1 0 1 0 1 0 0 1 1 2 2 3 3 ANO MNO 1 A 113 06/01/2010 129 06/02/2010 143 06/03/2010 209 05/04/2010 2 B 218 06/01/2010 211 06/02/2010 244 06/03/2010 348 05/04/2010 3 C 22 06/01/2010 114 06/02/2010 100 06/03/2010 151 05/04/2010 df = df.stack()[[1,0]].reset_index(level=2, drop=True).reset_index() df.columns = ['ANO','MNO','Time','Unit'] print (df) ANO MNO Time Unit 0 1 A 06/01/2010 113 1 1 A 06/02/2010 129 2 1 A 06/03/2010 143 3 1 A 05/04/2010 209 4 2 B 06/01/2010 218 5 2 B 06/02/2010 211 6 2 B 06/03/2010 244 7 2 B 05/04/2010 348 8 3 C 06/01/2010 22 9 3 C 06/02/2010 114 10 3 C 06/03/2010 100 11 3 C 05/04/2010 151 用于更改排序的交换列。

#last column is missing 
print (df)
   ANO MNO  UJ2010      DJ2010  UF2010      DF2010  UM2010      DM2010  UA2010
0    1   A     113  06/01/2010     129  06/02/2010     143  06/03/2010     209
1    2   B     218  06/01/2010     211  06/02/2010     244  06/03/2010     348
2    3   C      22  06/01/2010     114  06/02/2010     100  06/03/2010     151

编辑:

df = df.set_index(['ANO','MNO'])
#MultiIndex is created by first character of column names with all another
df.columns = [df.columns.str[0], df.columns.str[1:]]
print (df)
            U           D     U           D     U           D     U
        J2010       J2010 F2010       F2010 M2010       M2010 A2010
ANO MNO                                                            
1   A     113  06/01/2010   129  06/02/2010   143  06/03/2010   209
2   B     218  06/01/2010   211  06/02/2010   244  06/03/2010   348
3   C      22  06/01/2010   114  06/02/2010   100  06/03/2010   151


#stack add missing values, replace them by NaN
df = df.stack().reset_index(level=2, drop=True).reset_index()
df.columns = ['ANO','MNO','Time','Unit']
print (df)
    ANO MNO        Time  Unit
0     1   A         NaN   209
1     1   A  06/02/2010   129
2     1   A  06/01/2010   113
3     1   A  06/03/2010   143
4     2   B         NaN   348
5     2   B  06/02/2010   211
6     2   B  06/01/2010   218
7     2   B  06/03/2010   244
8     3   C         NaN   151
9     3   C  06/02/2010   114
10    3   C  06/01/2010    22
11    3   C  06/03/2010   100

position:relative;

答案 2 :(得分:0)

您可以将ilocpd.concat一起使用。解决方案很简单 - 只需将所有相关列(通过iloc选择)一个接一个地垂直堆叠并连接起来:

def rename(sub_df):
    sub_df.columns = ["ANO", "MNO", "Time", "Unit"]
    return sub_df

pd.concat([rename(df.iloc[:, [0, 1, x+1, x]])
           for x in range(2, df.shape[1], 2)])

    ANO     MNO     Time    Unit
0   1       A   06/01/2010  113
1   2       B   06/01/2010  218
2   3       C   06/01/2010  22
0   1       A   06/02/2010  129
1   2       B   06/02/2010  211
2   3       C   06/02/2010  114
0   1       A   06/03/2010  143
1   2       B   06/03/2010  244
2   3       C   06/03/2010  100
0   1       A   05/04/2010  209
1   2       B   05/04/2010  348
2   3       C   05/04/2010  151