Добавьте строки, если они отсутствуют, чтобы сохранить желаемую последовательность - PullRequest
0 голосов
/ 28 августа 2018

У меня есть фрейм данных, который выглядит следующим образом:

Hcode |  Hname | ctry | value
  1   |   a    |  X   |  34
  2   |   b    |  X   |  45
  1   |   a    |  Y   |  46
  2   |   b    |  Y   | 123
  3   |   c    |  Y   | 343
  1   |   a    |  Z   | 314
  2   |   b    |  Z   |  12

Я хотел бы иметь для каждого 'ctry' одинаковое количество строк. То есть каждый 'ctry' будет иметь строку Hname для a, b и c - независимо от того, существует ли соответствующее значение для данной строки.

То, что я ищу, выглядит примерно так:

Hcode |  Hname | ctry | value
  1   |   a    |  X   |  34
  2   |   b    |  X   |  45
  3   |   c    |  X   |  
  1   |   a    |  Y   |  46
  2   |   b    |  Y   | 123
  3   |   c    |  Y   | 343
  1   |   a    |  Z   | 314 
  2   |   b    |  Z   |  12
  3   |   c    |  Z   |

Чтобы немного усложнить ситуацию, мой столбец Hname состоит из 200 значений, например, а, б, в, ..., 200

У меня есть файл Excel со всеми 200 строками значений Hcode и Hname.

Как мне вставить эти дополнительные строки, которые будут содержать пустые значения в столбце value, используя информацию, хранящуюся в моем файле Excel?

РЕДАКТИРОВАТЬ :

@ piRSquared ответ отлично работает для вышеперечисленного. Но я попытался обобщить и добавить к коду, используя больший набор данных, и натолкнулся на следующую ошибку ValueError: Buffer has wrong number of dimensions (expected 1, got 2).

Мой расширенный набор данных выглядит так:

Hcode |  Hname | Hcateg | ctry | ctry_code | region| region_code| v1 | v2 
  1   |   a    |   A    |  X   |   XX      | AFR   |  1         | 34 |  5
  2   |   b    |   B    |  X   |   XX      | AFR   |  1         | 45 | 12
  1   |   a    |   A    |  Y   |   YY      | EUR   |  2         |    | 10
  2   |   b    |   B    |  Y   |   YY      | EUR   |  2         | 78 | 95
  3   |   c    |   C    |  Y   |   YY      | EUR   |  2         | 25 | 29
  1   |   a    |   A    |  Z   |   ZZ      | MAR   |  3         |    | 59 
  2   |   b    |   B    |  Z   |   zz      | MAR   |  3         | 98 | 75

Обратите внимание, что Hcode всегда соответствует одинаковым Hname и Hcateg. То же относится и к ctry и ctry_code. И снова то же самое относится к region и region_code.

Моя попытка:

cols = ['Hcode', 'Hname', 'Hcateg', 'ctry', 'ctry_code', 'region',
         'region_code']

df2 = pd.DataFrame([
    h + (c,)
    for c in df['ctry'].unique()
    for h in pd.factorize([*zip(df['Hcode'],
                                df['Hname'],
                                df['Hcateg'],
                                df['ctry_code'],
                                df['region'],
                                df['region_code'],)])[1]
                    ], columns=cols)

df2.merge(df, 'left')

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Создать фрейм данных для объединения с

cols = ['Hcode', 'Hname', 'ctry']
df2 = pd.DataFrame([
    h + (c,)
    for c in df.ctry.unique()
    for h in pd.factorize([*zip(df.Hcode, df.Hname)])[1]
], columns=cols)

df2.merge(df, 'left')

   Hcode Hname ctry  value
0      1     a    X   34.0
1      2     b    X   45.0
2      3     c    X    NaN
3      1     a    Y   46.0
4      2     b    Y  123.0
5      3     c    Y  343.0
6      1     a    Z  314.0
7      2     b    Z   12.0
8      3     c    Z    NaN

Обобщенный

hcols = ['Hcode', 'Hname', 'Hcateg']
ccols = ['ctry', 'ctry_code', 'region', 'region_code']

H = {*zip(*map(df.get, hcols))}
C = {*zip(*map(df.get, ccols))}

d2 = pd.DataFrame(
    [h + c for h in H for c in C],
    columns=hcols + ccols
)

d2.merge(df, 'left')

    Hcode Hname Hcateg ctry ctry_code region  region_code    v1    v2
0       2     b      B    X        XX    AFR            1  45.0  12.0
1       2     b      B    Y        YY    EUR            2  78.0  95.0
2       2     b      B    Z        ZZ    MAR            3   NaN   NaN
3       2     b      B    Z        zz    MAR            3  98.0  75.0
4       1     a      A    X        XX    AFR            1  34.0   5.0
5       1     a      A    Y        YY    EUR            2  10.0   NaN
6       1     a      A    Z        ZZ    MAR            3  59.0   NaN
7       1     a      A    Z        zz    MAR            3   NaN   NaN
8       3     c      C    X        XX    AFR            1   NaN   NaN
9       3     c      C    Y        YY    EUR            2  25.0  29.0
10      3     c      C    Z        ZZ    MAR            3   NaN   NaN
11      3     c      C    Z        zz    MAR            3   NaN   NaN
0 голосов
/ 28 августа 2018

Чтобы создать строку для каждого ctry, для каждого значения Hname, вы можете преобразовать свой DataFrame в Hname в качестве столбцов с unstack, а затем повторно сложить данные, сохранив пустое значения:

df.set_index(["ctry", "Hname"])["value"].unstack().stack(dropna=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...