& Ldquo; & амп; & Rdquo; vs & ldquo; + & rdquo; операторов в VB.NET [дубликат]

С DataFrames и UDF:

from pyspark.sql.types import ArrayType, StructType, StructField, IntegerType
from pyspark.sql.functions import col, udf

zip_ = udf(
  lambda x, y: list(zip(x, y)),
  ArrayType(StructType([
      # Adjust types to reflect data types
      StructField("first", IntegerType()),
      StructField("second", IntegerType())
  ]))
)

(df
    .withColumn("tmp", zip_("b", "c"))
    # UDF output cannot be directly passed to explode
    .withColumn("tmp", explode("tmp"))
    .select("a", col("tmp.first").alias("b"), col("tmp.second").alias("c"), "d"))

С RDDs:

(df
    .rdd
    .flatMap(lambda row: [(row.a, b, c, row.d) for b, c in zip(row.b, row.c)])
    .toDF(["a", "b", "c", "d"]))

Оба решения неэффективны из-за накладных расходов на Python. Если размер данных исправлен, вы можете сделать что-то вроде этого:

from functools import reduce
from pyspark.sql import DataFrame

# Length of array
n = 3

# For legacy Python you'll need a separate function
# in place of method accessor 
reduce(
    DataFrame.unionAll, 
    (df.select("a", col("b").getItem(i), col("c").getItem(i), "d")
        for i in range(n))
).toDF("a", "b", "c", "d")

или даже:

from pyspark.sql.functions import array, struct

# SQL level zip of arrays of known size
# followed by explode
tmp = explode(array(*[
    struct(col("b").getItem(i).alias("b"), col("c").getItem(i).alias("c"))
    for i in range(n)
]))

(df
    .withColumn("tmp", tmp)
    .select("a", col("tmp").getItem("b"), col("tmp").getItem("c"), "d"))

Это должно быть значительно быстрее по сравнению с UDF или RDD. Обобщены для поддержки произвольного количества столбцов:

# This uses keyword only arguments
# If you use legacy Python you'll have to change signature
# Body of the function can stay the same
def zip_and_explode(*colnames, n):
    return explode(array(*[
        struct(*[col(c).getItem(i).alias(c) for c in colnames])
        for i in range(n)
    ]))

df.withColumn("tmp", zip_and_explode("b", "c", n=3))
23
задан Peter Mortensen 19 March 2013 в 11:44
поделиться

6 ответов

Операторы + и & являются не одинаковыми в VB.NET.

Используя Оператор & указывает на ваше намерение объединить строки, а оператор + указывает на ваше намерение добавлять номера. Использование оператора & преобразует обе стороны операции в строки. Когда у вас смешанные типы (одна сторона выражения - это строка, другая - число), ваше использование оператора будет определять результат.

1 + "2" = 3 'This will cause a compiler error if Option Strict is on'
1 & "2" = "12"
1 & 2 = "12"
"text" + 2 'Throws an InvalidCastException since "text" cannot be converted to a Double'

Итак, моя рекомендация (кроме как избежать таких как смешивание) заключается в использовании & при конкатенации строк, чтобы убедиться, что ваши намерения понятны компилятору и избегают ошибок, которые невозможно найти, используя оператор + для конкатенации.

49
ответ дан bdukes 5 September 2018 в 07:37
поделиться

Независимо от многочисленных подсказок «придерживаться одного ИЛИ другого» - это сильно зависит от того, что вы комбинируете.

Короче говоря, я бы использовал «& amp;». для строк и «+» только для арифметических операций

Почему? Взгляните на https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/addition-operator#remarks

Все эти комбинации с переключением строгой опции похожи на то, как катить кости для компилятора ... и никогда не бывает очевидным для читателя.

Я также добавлю https://docs.microsoft.com / en-us / dotnet / visual-basic / programming-guide / language-features / operator-and-expressions / concatenation-operations # differ-between-the-two-concatenation-operations с понятным выражением:

Оператор + имеет основную цель добавления двух чисел.

0
ответ дан Bernhard 5 September 2018 в 07:37
поделиться

Амперсанд является рекомендуемым методом. Оператор плюс будет работать, иногда, для конкатенации строк, но не считается правильным и будет иногда приводить к непредвиденным результатам.

2
ответ дан Bob Mc 5 September 2018 в 07:37
поделиться

Они идентичны в VB.NET при работе с 2 строками. «& Amp;» оператор существует для обратной совместимости в VB 6 и ранее, где & amp; был оператором конкатенации строк и + не работал для текста.

Существует разница, если один из двух операндов не является строкой, поскольку bdukes указал . Однако в этой ситуации я настоятельно рекомендую использовать String.Format или StringBuilder (в зависимости от количества / типов операций) для построения результирующей строки из смешанных типов.

В целом я бы рекомендовал использовать +, по одной причине. Если вы когда-либо решили перевести код на другой язык (например, C #), оператор + будет больше соответствовать переведенной версии. Вероятно, для людей, приезжающих с другого языка, будет легче понять и следовать вашему коду.

2
ответ дан Community 5 September 2018 в 07:37
поделиться

Подумайте, лучше ли использовать String.Format при конкатенации строк. Обычно код заканчивается тем, что имеет больше смысла.

Кроме того, если вы много раз объединяетесь, рассмотрите возможность использования StringBuilder, а не String.

5
ответ дан Patrick Szalapski 5 September 2018 в 07:37
поделиться

В общем, & amp; всегда будет конкатенировать строки независимо от типов аргументов, а + не будет. Поскольку нет недостатка в использовании & amp; over + иначе, в ситуациях, когда вам явно нужны конкатенации строк, это предпочтительнее. Это также делает код более понятным.

3
ответ дан Pavel Minaev 5 September 2018 в 07:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: