Удалить строки, содержащие определенное значение в фрейме данных PySpark - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть фрейм данных pyspark:

ABC
1 NA 9
4 2 5
6 4 2
5 1 NA

Я хочу удалить строки, содержащие значение "NA".В этом случае первый и последний ряд.Как реализовать это, используя Python и Spark?


Обновление на основе комментария: поиск решения, которое удаляет строки, содержащие строку: NA в любом из множества столбцов.

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

В Scala я делал это по-другому, но добился этого с помощью pyspark.Не мой любимый ответ, но это из-за меньшего знания pyspark моей стороны.В Scala все кажется проще.В отличие от массива, нет глобального сопоставления со всеми столбцами, которые могут остановиться, как только найдется один.Динамический с точки зрения количества столбцов.

Допущения, сделанные для данных, не имеющих ~~ в качестве части данных, могли бы быть разделены на массив, но решили не делать этого здесь. Использование None вместо NA .

from pyspark.sql import functions as f

data = [(1,    None,    4,    None),
        (2,    'c',     3,    'd'),
        (None, None,    None, None),
        (3,    None,    None, 'z')]
df = spark.createDataFrame(data, ['k', 'v1', 'v2', 'v3'])

columns = df.columns
columns_Count = len(df.columns)

# colCompare is String
df2 = df.select(df['*'], f.concat_ws('~~', *columns).alias('colCompare') )
df3 = df2.filter(f.size(f.split(f.col("colCompare"), r"~~"))  == columns_Count).drop("colCompare")
df3.show()

возвращает:

+---+---+---+---+
|  k| v1| v2| v3|
+---+---+---+---+
|  2|  c|  3|  d|
+---+---+---+---+
0 голосов
/ 24 февраля 2019

Просто используйте фрейм данных фильтр выражение:

l = [('1','NA','9')
    ,('4','2', '5')
    ,('6','4','2')
    ,('5','NA','1')]
df = spark.createDataFrame(l,['A','B','C'])
#The following command requires that the checked columns are strings!
df = df.filter((df.A != 'NA') & (df.B != 'NA') & (df.C != 'NA'))
df.show()

+---+---+---+ 
|  A|  B|  C| 
+---+---+---+ 
|  4|  2|  5| 
|  6|  4|  2| 
+---+---+---+

@ bluephantom: В случае, если у вас есть сотни столбцов, просто сгенерируйте строковое выражение через понимание списка:

#In my example are columns need to be checked
listOfRelevantStringColumns = df.columns
expr = ' and '.join('(%s != "NA")' % col_name for col_name in listOfRelevantStringColumns)
df.filter(expr).show()
...