我有这样的 df :
ID Name Price
1 Fruit 10.5
1 xxx 10.5
1 yyy 8.5
1 Apple 4.2
1 aaa 4.1
1 bbb 0.1
1 Mango 2.1
1 abc 1
1 lmn
2 Fruit1 7.6 ### and so on for ID 2
df
上方具有以下属性:
ID 2,3,4
重复同样的事情……依此类推ID
,第一个订单项都会有所不同。例如Fruit
和Fruit1
Apple
个行项目,然后是Mango
预期输出:
ID Name Price Apple aaa bbb Mango
1 Fruit 10.5 4.2 4.1 0.1 2.1
2 Fruit1 7.6
问题:
1。我想要一个df,该df保留每个ID的第一行
2。取Apple
至Mango
的所有行,进行转置并放置其价格值
3。不在乎预期输出中的xxx
或abc
之类的行
我知道如何按ID groupby
或按列transpose
,但是不能仅对某些行求groupby + transpose
。
答案 0 :(得分:3)
public static boolean isAlphaNumericWithWhiteSpace(String text) {
return text != null && text.matches("^[\\p{L}\\p{N}ın\\s]*$");
}
我将使用一种有趣的排序技术来按正确的顺序获取内容。
seen = set()
result = []
current = None
apple = 'Apple'
mango = 'Mango'
fruit = {apple, mango}
for tup in df.itertuples():
if tup.ID not in seen:
result.append({'ID': tup.ID, 'Name': tup.Name})
current = result[-1]
seen.add(tup.ID)
elif mango not in current and (tup.Name in fruit or apple in current):
current[tup.Name] = tup.Price
d = pd.DataFrame(result)
d
Apple ID Mango Name aaa bbb
0 4.2 1 2.1 Fruit 4.1 0.1
1 40.2 2 20.1 Fruit1 40.1 10.1
key = lambda x: (x != 'ID', x != 'Name', x != 'Apple', x == 'Mango')
d[sorted(d, key=key)]
ID Name Apple aaa bbb Mango
0 1 Fruit 4.2 4.1 0.1 2.1
1 2 Fruit1 40.2 40.1 10.1 20.1
这并不完美,因为它不能保证仅保留def f(id_, d):
names = d.Name.to_numpy()
apple = names == 'Apple'
mango = np.append(False, names[:-1] == 'Mango')
a = np.logical_or.accumulate(apple)
m = np.logical_or.accumulate(mango)
mask = a ^ m
res = {'ID': id_, 'Name': d.Name.iloc[0], **dict(zip(names[mask], d.Price[mask]))}
return res
key = lambda x: (x != 'ID', x != 'Name', x != 'Apple', x == 'Mango')
pd.DataFrame([*map(f, *zip(*df.groupby('ID'),))]).pipe(lambda d: d[sorted(d, key=key)])
ID Name Apple aaa bbb Mango
0 1 Fruit 4.2 4.1 0.1 2.1
1 2 Fruit1 40.2 40.1 10.1 20.1
和'Apple'
之间的内容。
'Mango'