Преобразование широкоформатного формата в длинный на сервере sql и в информационном фрейме имеет около 1000 столбцов - Оптимизировать - PullRequest
2 голосов
/ 29 марта 2019

У меня есть датафрейм df в широком формате и около 1000 столбцов. Мне нужно преобразовать это в длинный формат

Пример таблицы:

 Date   TLRA_Equity  KAMN_Equity  B_Equity  ARNC_Equity RC_Equity DAR_Equity
1/1/2000  10              20        30          40        50          60
2/1/2000  15              25        35          45        55          65
3/1/2000  17              27        37          47        57          67

Я могу преобразовать это в длинный формат с расплавом данных и вставить в таблицу на python с кодом ниже

        df = df.melt(id_vars = 'Date')
        query = "insert into table values (?,?,?)"
        cursor.executemany(query, df.values.tolist())

Данные в длинном формате:

  investment        variable      value  
 1/1/2000      TLRA_Equity       10    
 1/1/2000      KAMN_Equity       20    
 1/1/2000      B_Equity          30 
 1/1/2000      ARNC_Equity       40

Но после преобразования длинного формата обновление занимает много времени. Есть ли способ вставить в таблицу базы данных в широкоформатном формате и преобразовать ее в длинный формат в sql, чтобы ускорить процесс.

Вывод при запуске решения «Джон Каппеллетти»

   Date         Item          Value
   1/1/2000     Date           1/1/2000
   1/1/2000     TLRA_x0020_Equity   10
   1/1/2000     KAMN_x0020_Equity   20
   1/1/2000     B_x0020_Equity      30
   1/1/2000     ARNC_x0020_Equity   40

1 Ответ

2 голосов
/ 29 марта 2019

Очевидно, что Unpivot будет более производительным, но есть подход, который будет «динамически» удалять ваши данные без использования динамического SQL.

Плюс в том, что вам не нужно указывать 1000 столбцов.

Пример

Select A.Date
      ,C.*
 From  YourTable A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
                Select Item  = xAttr.value('local-name(.)', 'varchar(100)')
                      ,Value = xAttr.value('.','varchar(max)')
                 From  XMLData.nodes('//@*') xNode(xAttr)
                 Where xAttr.value('local-name(.)','varchar(100)') not in ('Date')
             ) C

Возвращает

enter image description here

EDIT

 ...
,Item  = replace(xAttr.value('local-name(.)', 'varchar(100)'),'_x0020_',' ')
 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...