Groupby with mask and transform

时间:2015-12-03 04:00:25

标签: python pandas

我有一个这样的数据框:

POLY_KEY_I      Class     SP_Percent             
FS01080100SM001 NA               5.0
                MTGP            67.5
                Meadow          25.0
                Woodland         2.5
FS01080100SM002 PHP             85.0
                SP              15.0

,如果POLY_KEY_I == ClassMeadow> = SP_Percent我想将20转换为MTGP,则每个uniqe WMTGP {1}}。

我想要的输出是:

POLY_KEY_I      Class     SP_Percent             
FS01080100SM001 NA               5.0
                WMTGP           67.5
                Meadow          25.0
                Woodland         2.5
FS01080100SM002 PHP             85.0
                SP              15.0

我正在尝试的代码是:

df ['mask'] = ((df['Class'] == 'Meadow') & df['SP_Percent'] >=20)
mask = df.groupby(['POLY_KEY_I'])['mask'].transform('MTGP')
df.loc[mask,'Class']='WMTGP'
print(df)

但这会返回错误:

  

mask = final.groupby(['POLY_KEY_I'])['mask']。transform('MTGP')

     

文件“C:\ Users \ Stefano \ Anaconda2 \ lib \ site-packages \ pandas \ core \ groupby.py”,第2439行,转换           return self._transform_fast(lambda:getattr(self,func)(* args,** kwargs))

     

文件“C:\ Users \ Stefano \ Anaconda2 \ lib \ site-packages \ pandas \ core \ groupby.py”,第2484行,在_transform_fast中           values = func()。values

     

文件“C:\ Users \ Stefano \ Anaconda2 \ lib \ site-packages \ pandas \ core \ groupby.py”,第2439行,           return self._transform_fast(lambda:getattr(self,func)(* args,** kwargs))

     

文件“C:\ Users \ Stefano \ Anaconda2 \ lib \ site-packages \ pandas \ core \ groupby.py”,第520行, getattr           (键入(自我)。名称,attr))

     

AttributeError:'SeriesGroupBy'对象没有属性'MTGP

编辑:

我不知道这是否有帮助,但如果我改变这一行:

mask = df.groupby(['POLY_KEY_I'])['mask'].transform('MTGP')

到此:

mask = df.groupby(['POLY_KEY_I'])['mask'].transform('any')

它会将相应POLY_KEY_ID的每个值更改为WMTGP,但我只想更改MTGP

2 个答案:

答案 0 :(得分:2)

我使用groupby自定义函数apply完全将您的解决方案更改为f。对于检查字符串值,最好使用isin

输入(添加第5行进行测试):

        POLY_KEY_I     Class  SP_Percent
0  FS01080100SM001       NaN         5.0
1  FS01080100SM001      MTGP        67.5
2  FS01080100SM001    Meadow        25.0
3  FS01080100SM001  Woodland         2.5
4  FS01080100SM002       PHP        85.0
5  FS01080100SM002      MTGP        85.0
6  FS01080100SM002        SP        15.0    
def f(g):
    if ((g['Class'].isin(['Meadow'])) & (g['SP_Percent'] >=20)).any():
       g['Class'].loc[g['Class'].isin(['MTGP'])] = 'WMTGP'
       return g
    else:
       return g

print df.groupby(['POLY_KEY_I']).apply(f)
        POLY_KEY_I     Class  SP_Percent
0  FS01080100SM001       NaN         5.0
1  FS01080100SM001     WMTGP        67.5
2  FS01080100SM001    Meadow        25.0
3  FS01080100SM001  Woodland         2.5
4  FS01080100SM002       PHP        85.0
5  FS01080100SM002      MTGP        85.0
6  FS01080100SM002        SP        15.0

EDIT1:

添加时间:

%timeit df.groupby(['POLY_KEY_I']).apply(f)
100 loops, best of 3: 4.78 ms per loop

%timeit shahram(df)
10 loops, best of 3: 38.2 ms per loop

计时来源:

import pandas as pd
import numpy as np
import io

temp=u"""POLY_KEY_I;Class;SP_Percent
FS01080100SM001;NA;5.0
FS01080100SM001;MTGP;67.5
FS01080100SM001;Meadow;25.0
FS01080100SM001;Woodland;2.5
FS01080100SM002;PHP;85.0
FS01080100SM002;MTGP;85.0
FS01080100SM002;SP;15.0"""

df = pd.read_csv(io.StringIO(temp), sep=";", index_col=None, parse_dates=False)
print df
print df.dtypes
print df.index

def shahram(df):
    df ['mask'] = ((df['Class'] == 'Meadow') & (df['SP_Percent'] >=20))
    df2 = df[(df['mask']==True)][['POLY_KEY_I']]
    df2['mask2']=True
    df = pd.merge(df,df2,how='left')
    df.ix[((df['mask2']==True) & (df['Class']=='MTGP')),'Class'] = 'WMTGP'
    return df

def f(g):
    if ((g['Class'].isin(['Meadow'])) & (g['SP_Percent'] >=20)).any():
       g['Class'].loc[g['Class'].isin(['MTGP'])] = 'WMTGP'
       return g
    else:
       return g

print df.groupby(['POLY_KEY_I']).apply(f)
print shahram(df)

答案 1 :(得分:1)

我是这样做的:

// FroggerComponent.java

     import java.awt.*;
     import java.awt.event.*;
     import javax.swing.*;
     import java.io.*;
    import javax.imageio.*;
    public class FroggerComponent extends JComponent {
// Size of the game grid
public static final int WIDTH = 20;
public static final int HEIGHT = 7;
// Initial pixel size for each grid square
public static final int PIXELS = 50;
// Image filenames for car, lily, and frog
public static final String[] IMAGES = new String[] { "Images/frog.png", "Images/car.png", "Images/lily.png" };
// Colors for ROAD, WATER, and DIRT
public static final Color[] COLORS = new Color[] { Color.BLACK, Color.BLUE, Color.GRAY };
// Codes to store what is in each square in the grid
public static final int EMPTY = 0;
public static final int CAR = 1;
public static final int LILY = 2;
private Image frog;
private Image car;
private Image lily;

private int[][] grid = new int[WIDTH][HEIGHT];
Row[] rows = new Row[HEIGHT];
private int x;
private int y;
int x1 = 6;
int y1 = 10;
int dx;
private int dy;

private boolean dead;

/*
 * Provided utility method to read in an Image object. If the image cannot
 * load, prints error output and returns null. Uses Java standard
 * ImageIO.read() method.
 */
private Image readImage(String filename) {
    Image image = null;
    try {
        image = ImageIO.read(new File(filename));
    } catch (IOException e) {
        System.out.println("Failed to load image '" + filename + "'");
        e.printStackTrace();
    }
    return (image);
}

private void readRow(String file) {
    try {
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        String line = br.readLine();
        int count = 1;
        while ((line != null) && (line != "\n") && (line != "\r")) {
            Row r = new Row(line);
            rows[count] = r;
            line = br.readLine();
            count++;
        }
    } catch (IOException ex) {
        System.out.println("File not found!");
    }

}

public FroggerComponent(String filename) {
    setPreferredSize(new Dimension(WIDTH * PIXELS, HEIGHT * PIXELS));
    readRow(filename);
    /*
     * Add your code here ... readImage(...); ...
     */

    frog = readImage("images/frog.png");
    lily = readImage("Images/lily.png");
    car = readImage("Images/car-red.png");
    readRow("Images/world.txt");
    reset();

}

public void reset() {
    for (int x = 0; x < grid.length; x++)
        for (int y = 0; y < grid[x].length; y++)
            grid[x][y] = EMPTY;
    dead = false;
    x = 0;
    y = 6;
    repaint();
}

private void moveBy(int dx, int dy) {
    if ((x1 + dx >= 0 && x + dx < WIDTH) && (y1 + dy >= 0 && y1 + dy < HEIGHT)) {
        x1 += dx;
        y1 += dy;
    }
}

public boolean isWin() {
    return (y == 0);
}

public void key(int code) throws ArrayIndexOutOfBoundsException {
    /*
     * Add your code here
     */

    if (code == KeyEvent.VK_UP) {
        x1 = x1 - 1;

    } else if (code == KeyEvent.VK_DOWN) {
        x1 = x1 + 1;
    } else if (code == KeyEvent.VK_LEFT) {

        y1 = y1 - 1;
    } else if (code == KeyEvent.VK_RIGHT) {
        y1 = y1 + 1;
    }

    this.repaint();

}

public void paintComponent(Graphics g) {
    /*
     * Add your code here
     * 
     * 
     */
    // variables
    int squareWidth = getWidth() / grid.length;
    int squareHeight = getHeight() / grid[0].length;

    // paints the rows

    for (int y = 0; y < 20; y++) {
        if (grid[y][x] == EMPTY) {
            g.setColor(Color.GRAY);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    x++;
    for (int y = 0; y < 20; y++) {

        if (grid[y][x] == EMPTY) {
            g.setColor(Color.BLUE);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    x++;
    for (int y = 0; y < 20; y++) {

        if (grid[y][x] == EMPTY) {
            g.setColor(Color.BLACK);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    x++;
    for (int y = 0; y < 20; y++) {

        if (grid[y][x] == EMPTY) {
            g.setColor(Color.BLUE);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    x++;
    for (int y = 0; y < 20; y++) {

        if (grid[y][x] == EMPTY) {
            g.setColor(Color.BLUE);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    x++;
    for (int y = 0; y < 20; y++) {

        if (grid[y][x] == EMPTY) {
            g.setColor(Color.BLACK);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    x++;
    for (int y = 0; y < 20; y++) {

        if (grid[y][x] == EMPTY) {
            g.setColor(Color.GRAY);
            g.fillRect(squareWidth * y, squareWidth * x, squareWidth, squareHeight);
        }
    }
    // frog

    g.drawImage(frog, squareWidth * y1, squareHeight * x1, squareWidth, squareHeight, this);

    // lilypads
    g.drawImage(lily, squareWidth, squareHeight, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 5, squareHeight, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 10, squareHeight, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 10, squareHeight * 3, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 8, squareHeight * 3, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 3, squareHeight * 3, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 2, squareHeight * 4, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 4, squareHeight * 4, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 12, squareHeight * 4, squareWidth, squareHeight, null);
    g.drawImage(lily, squareWidth * 17, squareHeight * 4, squareWidth, squareHeight, null);
    // cars
    g.drawImage(car, squareWidth * 2, squareHeight * 5, squareWidth, squareHeight, null);
    g.drawImage(car, squareWidth * 5, squareHeight * 5, squareWidth, squareHeight, null);
    g.drawImage(car, squareWidth * 11, squareHeight * 5, squareWidth, squareHeight, null);
    g.drawImage(car, squareWidth * 7, squareHeight * 2, squareWidth, squareHeight, null);
    g.drawImage(car, squareWidth * 4, squareHeight * 2, squareWidth, squareHeight, null);

}

public void tick(int round) {
    /*
     * Add your code here
     */
}