<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def clip(self, shp, keep=False, *args, **kwargs):
        '''
        Clip raster using shape, where shape is either a GeoPandas DataFrame, shapefile,
        or some other geometry format used by python-raster-stats

        Returns list of GeoRasters or Pandas DataFrame with GeoRasters and additional information

        Usage:

        clipped = geo.clip(shape, keep=False)

        where:
        keep: Boolean (Default False), returns Georasters and Geometry information
        '''
        df = pd.DataFrame(zonal_stats(shp, self.raster, nodata=self.nodata_value, all_touched=True,
                                      raster_out=True, affine=Affine.from_gdal(*self.geot),
                                      geojson_out=keep,))
        if keep:
            df['GeoRaster'] = df.properties.apply(lambda x: GeoRaster(x['mini_raster_array'],
                                                                      Affine.to_gdal(x['mini_raster_affine']),
                                                                      nodata_value=x['mini_raster_nodata'],
                                                                      projection=self.projection,
                                                                      datatype=self.datatype))
            cols = list(set([i for i in df.properties[0].keys()]).intersection(set(shp.columns)))
            df2 = pd.DataFrame([df.properties.apply(lambda x: x[i]) for i in cols
                                ]).T.merge(df[['GeoRaster']], left_index=True, right_index=True,)
            df2.columns = cols+['GeoRaster']
            df2 = df2.merge(df[['id']], left_index=True, right_index=True)
            df2.set_index('id', inplace=True)
            return df2
        else:
            df['GeoRaster'] = df.apply(lambda x: GeoRaster(x.mini_raster_array,
                                                           Affine.to_gdal(x.mini_raster_affine),
                                                           nodata_value=x.mini_raster_nodata,
                                                           projection=self.projection,
                                                           datatype=self.datatype), axis=1)
            return df['GeoRaster'].values