我有一个这样的数据框:
Name ID Level
Name1 A 1
Name2 B 2
Name3 C 3
Name4 D 1
Name5 E 2
Name6 F 1
等...
我正在寻找一种基于名称标准仅提取此数据框的一部分的方法。因此,我想从Name4开始提取所有内容,直到该组中最后一个人的名字是另一个Level1。即从Name4提取到Name5,因为Name6是Level 1。
或者再举一个例子,我想从Name1提取到Name3,因为Name4是Level 1。
我可以使用宏在Excel中执行此操作...查找Name1,查看“级别”列,如果它不是1,则获取这一行数据并继续操作,直到您击中“名称”为止再次具有1级,然后停止,然后输出此部分
希望这很有道理。
答案 0 :(得分:1)
您可以执行以下操作:
创建一个包含组值的新列“ Group”,然后您可以groupby
此列
g = 0
for i in df.index:
if df.loc[i, "Level"] == 1:
g += 1
df.loc[i, "Group"] = g
答案 1 :(得分:1)
使用此数据框:
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
答案 2 :(得分:0)
您可以执行以下操作:
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
让我知道这是否有帮助。
答案 3 :(得分:0)
这会将所需的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()
答案 4 :(得分:0)
设置数据框:
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标记,然后累加。
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列进行分组操作...