Извлеките подраздел данных Pandas - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть такой кадр данных:

Name   ID   Level
Name1   A     1
Name2   B     2
Name3   C     3
Name4   D     1
Name5   E     2
Name6   F     1

и т.д.Поэтому я хочу извлечь все из Name4 и далее, пока имя последнего человека в этой группе не станет другим уровнем 1..ie Извлечь из Name4 в Name5, так как Name6 - это уровень 1.

Или, как еще один пример, яхочу извлечь из Name1 в Name3, поскольку Name4 - это уровень 1.

Я могу сделать это в Excel, используя макрос, который будет проходить по линиям ... Найдите Name1, посмотрите на столбец Level и, если онне 1, затем возьмите этот ряд данных и продолжайте до тех пор, пока не нажмете Имя, которое снова имеет Уровень 1, затем остановитесь, а затем выведите этот раздел

Надеюсь, это имеет смысл.

Ответы [ 5 ]

0 голосов
/ 21 ноября 2018

Установочный кадр данных:

df = pd.DataFrame({'Name': ['Name1', 'Name2', 'Name3', 'Name4', 'Name5', 'Name6'],
                   'ID': ['A', 'B', 'C', 'D', 'E', 'F'],
                   'Level': [1, 2, 3, 1, 2, 1]})

Найдите местоположение новых групп (новый уровень 1), используя сдвиг серии, отметьте 1, затем выполните cumsum.

grp_markers = (df.Level - df.Level.shift()).fillna(-1).values <= 0
df['grp'] = grp_markers.cumsum()

Найти подмножествакак это:

df[df.grp == 2]

    Name ID  Level    grp
3  Name4  D      1      2
4  Name5  E      2      2

Теперь вы также можете делать групповые вещи с помощью столбца grp ...

0 голосов
/ 21 ноября 2018

Это принесет необходимые Name в одном месте -

df.groupby(df.groupby(['Level']).cumcount())['Name'].apply(lambda x: ','.join(x))

0    Name1,Name2,Name3
1          Name4,Name5
2                Name6
Name: Name, dtype: object

Теперь вы можете установить Level для каждой из сущностей согласно вашим потребностям / манипулировать lambda в apply() функция, как вы хотите реализовать

0 голосов
/ 21 ноября 2018

Вы можете сделать что-то вроде этого:

Создать новый столбец «Группа», который содержит значение группы, и затем вы можете groupby этот столбец

g = 0
for i in df.index:
    if df.loc[i, "Level"] == 1:
        g += 1
    df.loc[i, "Group"] = g
0 голосов
/ 21 ноября 2018

Используя этот фрейм данных:

In [0]: df
Out[0]: 
    Name ID  Level
0  Name1  A      1
1  Name2  B      2
2  Name3  C      3
3  Name4  D      1
4  Name5  E      2
5  Name6  F      1

Используйте вспомогательный столбец / серию, которая указывает, имеет ли строка определенный уровень (целевой уровень).target_lvl = 1:

helper_series = (df['Level'] == target_lvl)

In [1]: helper_series
Out[1]: 
0     True
1    False
2    False
3     True
4    False
5     True

Теперь вы можете взять список диапазонов, который отображает начало и конец каждого подмножества:

ranges = df.index.where(helper_series).dropna().astype(int).tolist()

In [2]: ranges
Out[2]:
[0, 3, 5]

Обратите внимание, что значения ranges являются индексомкаждой строки, которая принадлежит target-lvl.

Наконец, вам просто нужно извлечь подмножества из ranges:

subsets = list()
for i in range(len(ranges)):
    if i == 0:
        continue
    subsets.append(df.iloc[ ranges[i-1] : ranges[i] , :])

last_subset = df.iloc[ ranges[-1] :, :]
if not last_subset.empty:    
    subsets.append(last_subset)

In [3]: subsets
Out[3]:
   Name  ID  Level  
0  Name1  A    1    
1  Name2  B    2  
2  Name3  C    3 

   Name  ID  Level  
3  Name4  D    1  
4  Name5  E    2
0 голосов
/ 21 ноября 2018

Вы можете сделать что-то вроде этого:

In [513]: df['new'] = df.Level.diff().fillna(0)  
# Create a column 'new' which holds the difference of Level across rows. 
# A negative value here means, level has re-started.

In [514]: df
Out[514]: 
    Name ID  Level  new
0  Name1  A      1  0.0
1  Name2  B      2  1.0
2  Name3  C      3  1.0
3  Name4  D      1 -2.0
4  Name5  E      2  1.0
5  Name6  F      1 -1.0

In [521]: l = df[df.new <0].index  # negative value of column new means, the level has re-started.

In [524]: d = dict() # A dictionary to hold sub-sections of the dataframe

In [530]: for c,i in enumerate(l):
     ...:     if c == 0:
     ...:         d[i] = df.iloc[0:i, :3]
     ...:     else:
     ...:         d[i] = df.iloc[l[c-1]:i, :3]
     ...:         

In [532]: for i in d.keys():  ## Print the multiple smaller dataframes
     ...:     print(d[i])
     ...:     
    Name ID  Level
0  Name1  A      1
1  Name2  B      2
2  Name3  C      3
    Name ID  Level
3  Name4  D      1
4  Name5  E      2

Дайте мне знать, если это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...