У нас есть два кадра данных, первый содержит некоторые значения с плавающей запятой (что означает среднюю скорость).
0 1 2
1 15.610826 19.182879 6.678087
2 13.740250 15.666897 17.640749
3 2.379010 2.889702 2.955097
4 20.540628 9.661226 9.479921
И еще датафрейм с географическими координатами, где происходит средняя скорость.
0 1 2
1 [52.2399255, 21.0654495] [52.23893150000001, 21.06087] [52.23800850000001,21.056779]
2 [52.2449705, 21.0755175] [52.2452905, 21.075118000000003] [52.245557500000004, 21.0748175]
3 [52.2401885, 21.012981500000002] [52.239134, 21.009432] [52.238420500000004, 21.007080000000002]
4 [52.221506500000004, 20.9665085] [52.222458, 20.968952] [52.224409, 20.969248999999998]
Теперь я хочу создать список с координатами, где средняя скорость выше 18, в этом случае это будет
list_above_18=[[52.23893150000001, 21.06087] , [52.221506500000004, 20.9665085]]
Как я могу выбрать значения из фрейма данных на основе значений в другом фрейме данных?
Вам следует избегать циклов, особенно в случае с pandas и numpy. Векторизуйте везде, где это возможно, так как это будет быстрее
Вы можете использовать перечисление, чтобы сжать кадры данных и работать с элементами отдельно. См. ниже (A, B - ваши кадры данных в том же порядке, в котором вы их предоставили):
list_above_18=[]
p=list(enumerate(zip(A.values, B.values)))
for i in p:
for k in range(3):
if i[1][0][k]>18:
list_above_18.append(i[1][1][k])
Выход:
>>>print(list_above_18)
[[52.23893150000001, 21.06087] , [52.221506500000004, 20.9665085]]
Учитывая, что форма набора данных средней скорости останется такой же, как и набор данных координат, вы можете попробовать следующее:
coord_df[data_df.iloc[:,:] > 18].T.stack().values
Здесь, coord_df = DataFrame со значениями координат data_df = средние значения скорости
Это вернет массив numpy только со значениями координат, где средняя скорость больше 18.
Как это работает:
data_df.iloc[:,:] > 18
Создает маску фрейма данных, так что все значения меньше 18 помечаются как False, а остальные — как True.
coord_df[data_df.iloc[:,:] > 18]
Передает маску в целевом кадре данных, т.е. кадре данных координат, который затем приводит к кадру данных, который показывает значения координат только для тех ячеек, где маска имеет значение True, то есть где средняя скорость была выше 18
.T.stack().values
Затем это извлекает только ненулевые значения из результирующего фрейма данных и возвращает массив numpy
Ссылки, которые я взял:
Пусть первая DF будет df1, а вторая DF будет df2
output_array = df2[df1>18].values.flatten() # df1>18 would create the mask
output_array = [val for val in output_array if type(val) == list] # removing the nan values. We can't use np.isnan as it would not work for list
Пример ввода:
df1
дф2
выход_массив
[[15.1, 20.5], [91.5, 95.8]]
У меня нет возможности что-либо протестировать здесь, поскольку вы не предоставили достаточно кода, но вы можете попробовать создать такие маски;
mask = df1.loc[:, 0] > 18
, а затем использовать их для фильтрации ваших фреймов данных следующим образом;df2.loc[mask, 0]
. Это просто маска для 0-го столбца.