Записать новый датафрейм из предыдущего

Есть df, со столбцами. https://wdho.ru/mqQQ . Как сделать новый датафрейм, в котором строки создаются только по принципу: "Md" не равно предыдущему значению (например "Md"=2, предыдущее =1) - пишем в новую строку new_df = "Date" = 5-Jan-18, "State bef" = 210.35K. И после когда "Md" не будет равно следующему значению (например "Md"=2, следующее =3), допишем в строку еще и "State after" = 269.51K И так со всеми.

"Date"  "State bef" "State after"   "Md"
2-Jan-18    211.74K      119.34K    1
3-Jan-18    260.86K      81.03K     1
4-Jan-18    246.15K      21.88K     1
5-Jan-18    183.45K      284.02K    1
8-Jan-18    210.35K      226.45K    2
9-Jan-18    319.92K      175.36K    2
10-Jan-18   290.54K      200.58K    2
11-Jan-18   341.94K      228.99K    2
12-Jan-18   302.10K      269.51K    2
15-Jan-18   173.46K      197.06K    3
16-Jan-18   322.95K      228.74K    3
17-Jan-18   280.42K      220.34K    3
18-Jan-18   270.23K      242.75K    3
19-Jan-18   278.36K      298.11K    3
22-Jan-18   250.60K      227.20K    4
23-Jan-18   343.73K      217.16K    4
24-Jan-18   308.37K      249.10K    4
25-Jan-18   301.93K      201.24K    4
26-Jan-18   227.60K      300.69K    4
29-Jan-18   202.24K      199.66K    5
30-Jan-18   135.87K      235.09K    5
31-Jan-18   20.43K       101.08K    5
1-Feb-18    336.92K      179.66K    5
2-Feb-18    307.13K      130.44K    5
5-Feb-18    335.64K      90.22K     6
6-Feb-18    328.85K      25.83K     6

На выходе получается:

df = pd.read_csv('a_red.csv')

2-Jan-18    211.74K      284.02K    1
8-Jan-18    210.35K      269.51K    2
15-Jan-18   173.46K      298.11K    3
22-Jan-18   250.60K      300.69K    4
29-Jan-18   202.24K      130.44K    5

СПАСИБО!


Ответы (3 шт):

Автор решения: CrazyElf

Ну элементарно же, если мыслить векторно (что часто требуется при работе с Numpy и Pandas):

import pandas as pd
df = pd.read_csv('a_red.csv')
df.loc[df['"Md"'].diff().fillna(1) > 0]

Берём разницу между значениями колонки Md и отбираем в df только строки, где эта разница есть (т.е. не 0). Ну и ещё из-за того, что в первой строке разница будет NA, надо заполнить это NA значением, например 1, перед проверкой.

Вывод:

    "Date"  "State bef" "State after"   "Md"    Unnamed: 4  Unnamed: 5  Unnamed: 6  Unnamed: 7
0   2-Jan-18    211.74K 119.34K 1   NaN NaN NaN 
4   8-Jan-18    210.35K 226.45K 2   NaN NaN NaN NaN
9   15-Jan-18   173.46K 197.06K 3   NaN NaN NaN NaN
14  22-Jan-18   250.60K 227.20K 4   NaN NaN NaN NaN
19  29-Jan-18   202.24K 199.66K 5   NaN NaN NaN NaN
24  5-Feb-18    335.64K 90.22K  6   NaN NaN NaN NaN
...

Update: Не заметил сначала условие про "State after", подумаю ещё.

Ну тогда такой вариант, только остаётся ещё заполнить последнее значение в колонке "State after", сейчас там NaN, пока не придумал хороший красивый вариант:

import pandas as pd
df = pd.read_csv('a_red.csv')
df1 = df.copy()
df1['"State after"'] = df['"State after"'].shift(1)
df1 = df1.loc[df['"Md"'].diff(1).fillna(1) > 0]
df1['"State after"'] = df1['"State after"'].shift(-1)
df1

Вывод:

    "Date"  "State bef" "State after"   "Md"    Unnamed: 4  Unnamed: 5  Unnamed: 6  Unnamed: 7
0   2-Jan-18    211.74K 284.02K 1   NaN NaN NaN 
4   8-Jan-18    210.35K 269.51K 2   NaN NaN NaN NaN
9   15-Jan-18   173.46K 298.11K 3   NaN NaN NaN NaN
14  22-Jan-18   250.60K 300.69K 4   NaN NaN NaN NaN
19  29-Jan-18   202.24K 130.44K 5   NaN NaN NaN NaN
24  5-Feb-18    335.64K 277.12K 6   NaN NaN NaN NaN
→ Ссылка
Автор решения: strawdog

Можно так попробовать:

import pandas as pd

df=pd.read_csv("a_red.csv")

res = df.groupby('"Md"').agg({'"Date"': lambda x: x.iloc[0],
      '"State bef"': lambda x: x.iloc[0],
      '"State after"': lambda x: x.iloc[-1]})

тогда res будет:

         "Date" "State bef" "State after"
"Md"                                     
1      2-Jan-18     211.74K       284.02K
2      8-Jan-18     210.35K       269.51K
3     15-Jan-18     173.46K       298.11K
4     22-Jan-18     250.60K       300.69K
5     29-Jan-18     202.24K       130.44K
6      5-Feb-18     335.64K       277.12K
7     12-Feb-18     349.67K       315.27K
8     19-Feb-18     125.63K       275.87K
9     26-Feb-18     188.30K       130.53K
10     5-Mar-18     261.06K       345.22K
11    12-Mar-18     240.03K       319.09K
12    19-Mar-18     272.42K       336.60K
13    26-Mar-18     183.69K       513.72K
14     2-Apr-18     190.05K       115.19K
15     9-Apr-18     257.50K       290.88K
16    16-Apr-18     297.44K       445.04K
17    23-Apr-18     317.45K       417.01K
18    30-Apr-18      24.76K       271.17K
19     7-May-18     230.47K       277.42K
20    14-May-18     290.13K       235.33K
21    21-May-18     245.77K       398.56K
22    28-May-18      65.10K        77.00K
23     4-Jun-18     324.29K       278.36K
24    11-Jun-18     231.28K       300.92K

UPDATE (после уточнений задачи)

Вы можете группировать именно так, как вам нужно следующим образом:

Примерный Df с повторяющимися значениями Md:
       "Date" "State bef" "State after"  "Md"  Unnamed: 4  Unnamed: 5  ...
0    2-Jan-18     211.74K       119.34K     1         NaN         NaN   
1    3-Jan-18     260.86K        81.03K     1         NaN         NaN   
2    4-Jan-18     246.15K        21.88K     1         NaN         NaN   
3    5-Jan-18     183.45K       284.02K     1         NaN         NaN   
4    8-Jan-18     210.35K       226.45K     2         NaN         NaN   
5    9-Jan-18     319.92K       175.36K     2         NaN         NaN   
6   10-Jan-18     290.54K       200.58K     2         NaN         NaN   
7   11-Jan-18     341.94K       228.99K     2         NaN         NaN   
8   12-Jan-18     302.10K       269.51K     2         NaN         NaN   
9   15-Jan-18     173.46K       197.06K     1         NaN         NaN   
10  16-Jan-18     322.95K       228.74K     1         NaN         NaN   
11  17-Jan-18     280.42K       220.34K     1         NaN         NaN   
12  18-Jan-18     270.23K       242.75K     3         NaN         NaN   
13  19-Jan-18     278.36K       298.11K     3         NaN         NaN   
14  22-Jan-18     250.60K       227.20K     4         NaN         NaN   
15  23-Jan-18     343.73K       217.16K     4         NaN         NaN   
16  24-Jan-18     308.37K       249.10K     4         NaN         NaN   
17  25-Jan-18     301.93K       201.24K     4         NaN         NaN   
18  26-Jan-18     227.60K       300.69K     4         NaN         NaN   
19  29-Jan-18     202.24K       199.66K     2         NaN         NaN   
20  30-Jan-18     135.87K       235.09K     2         NaN         NaN 

Тогда:

res = df.groupby([(df['"Md"'] != df['"Md"'].shift()).cumsum()]).agg({'"Date"': lambda x: x.iloc[0],
      '"State bef"': lambda x: x.iloc[0],
      '"State after"': lambda x: x.iloc[-1]})

даст нам res:

         "Date" "State bef" "State after"
"Md"                                     
1      2-Jan-18     211.74K       284.02K
2      8-Jan-18     210.35K       269.51K
3     15-Jan-18     173.46K       220.34K
4     18-Jan-18     270.23K       298.11K
5     22-Jan-18     250.60K       300.69K
6     29-Jan-18     202.24K       235.09K
→ Ссылка
Автор решения: Sergey

Вот такая программулька:

import pandas as pd

df = pd.read_csv('~/tmp/a_red.csv', sep=',')
df_new = pd.DataFrame(df.iloc[0])

for row in range(1, df.shape[0]-1):
    if df.iloc[row]['"Md"'] != df.iloc[row-1]['"Md"']:
        df_new.append(df.iloc[row], ignore_index=True)
        print (row, ') ', df.iloc[row]['"Date"'], df.iloc[row]['"State bef"'], df.iloc[row]['"State after"'], df.iloc[row]['"Md"'])

Выдаёт такую подборку данных:

4 )  8-Jan-18 210.35K 226.45K 2
9 )  15-Jan-18 173.46K 197.06K 3
14 )  22-Jan-18 250.60K 227.20K 4
19 )  29-Jan-18 202.24K 199.66K 5
24 )  5-Feb-18 335.64K 90.22K 6
29 )  12-Feb-18 349.67K 274.79K 7
34 )  19-Feb-18 125.63K 298.14K 8
39 )  26-Feb-18 188.30K 300.16K 9
44 )  5-Mar-18 261.06K 124.00K 10
49 )  12-Mar-18 240.03K 361.25K 11
54 )  19-Mar-18 272.42K 482.51K 12
59 )  26-Mar-18 183.69K 359.01K 13
63 )  2-Apr-18 190.05K 366.65K 14
68 )  9-Apr-18 257.50K 34.70K 15
73 )  16-Apr-18 297.44K 361.36K 16
78 )  23-Apr-18 317.45K 379.72K 17
83 )  30-Apr-18 24.76K 334.98K 18
88 )  7-May-18 230.47K 150.81K 19
93 )  14-May-18 290.13K 256.24K 20
98 )  21-May-18 245.77K 246.92K 21
103 )  28-May-18 65.10K 319.37K 22
108 )  4-Jun-18 324.29K 102.59K 23
113 )  11-Jun-18 231.28K 321.11K 24

Первая строка df_new не распечатывается, так как она вставляется сразу же, до цикла.

→ Ссылка