以特定字符串开头的Groupby + Transpose列

时间:2019-05-30 13:22:07

标签: python pandas

我有这样的 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上方具有以下属性:

  1. ID 2,3,4重复同样的事情……依此类推
  2. 对于每个ID,第一个订单项都会有所不同。例如FruitFruit1
  3. 对于每个ID,总会有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。取AppleMango的所有行,进行转置并放置其价格值

3。不在乎预期输出中的xxxabc之类的行

我知道如何按ID groupby或按列transpose,但是不能仅对某些行求groupby + transpose

1 个答案:

答案 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

实验#2

这并不完美,因为它不能保证仅保留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'