熊猫:在列之间交换行

时间:2019-12-27 19:53:29

标签: python pandas dataframe

某些行输入错误的列,所以现在我需要交换它们。

df = pd.DataFrame({'c': {0: '22:58:00', 1: '23:03:00', 2: '0', 3: '10'}, 'a': {0: '0', 1: '10', 2: '22:58:00', 3: '23:03:00'}, 'd': {0: '23:27:00', 1: '23:39:00', 2: '10', 3: '17'}, 'b': {0: '10', 1: '17', 2: '23:27:00', 3: '23:39:00'}})

          a         b         c         d
0         0        10  22:58:00  23:27:00
1        10        17  23:03:00  23:39:00
2  22:58:00  23:27:00         0        10
3  23:03:00  23:39:00        10        17

我目前的做法

cpy = df[['a', 'b']]
df.loc[2:, 'a'] = df['c']
df.loc[2:, 'b'] = df['d']
df.loc[2:, 'c'] = cpy['a']
df.loc[2:, 'd'] = cpy['b']

预期产量

    a   b         c         d
0   0  10  22:58:00  23:27:00
1  10  17  23:03:00  23:39:00
2   0  10  22:58:00  23:27:00
3  10  17  23:03:00  23:39:00

它可以工作,但这仅是可行的,因为它只有4列。 有更好的方法吗?

请注意,dtypes可能导致排序问题 df.loc[0]['c']datetime.time(22, 58)

也许有类似的东西

df.swap_row_col(index=[2:], columns_from=['a', 'b'], columns_to=['c', 'd'])

3 个答案:

答案 0 :(得分:2)

方法1:np.sort

np.sortpd.DataFrame构造函数对我有用:

df = pd.DataFrame(np.sort(df.astype(str)), columns=df.columns)

    a   b         c         d
0   0  10  22:58:00  23:27:00
1  10  17  23:03:00  23:39:00
2   0  10  22:58:00  23:27:00
3  10  17  23:03:00  23:39:00

方法2:

更一般地说,通过检查哪些行与您的日期模式匹配,反之亦然,然后将这些值与bfillffill交换:

match_pattern = df.apply(lambda x: x.str.match('\d{2}:\d{2}:\d{2}'))

numeric = df.where(~match_pattern).bfill(axis=1).dropna(how='any', axis=1)
dates = df.where(match_pattern).ffill(axis=1).dropna(how='any', axis=1)

df = pd.concat([numeric, dates], axis=1)

    a   b         c         d
0   0  10  22:58:00  23:27:00
1  10  17  23:03:00  23:39:00
2   0   0  23:27:00  23:27:00
3  10  10  23:39:00  23:39:00

答案 1 :(得分:2)

如果原始订单是100,0,我的输出仍是100,0,也许我们可以在我的解决方案中尝试在此处注意

<FloatingInput
  ref={r => (this.phone = r)}
  value={this.state.phone}
  label={'Phone'}
  keyboardType={'numeric'}
  maxLength={14}
  labelColorBlur={'#FFFFFF'}
  onChangeText={this.onChangePhone}
  blurOnSubmit={false}
  icon={faPhone}
  onSubmitEditing={() => this.password.getInnerRef().focus()}
/>

onChangePhone = (text) => {
    let input = text.replace(/[(\-) ]/g,'');
    const size = input.length;
    if (input === '(') {
      input = '';
    } else if (size == 0) {
      input = input;
    } else if (size < 4) {
      input = '(' + input;
    } else if (size < 7) {
      input = '(' + input.substring(0,3) + ') ' + input.substring(3,6);
    } else {
      input = '(' + input.substring(0,3) + ') ' + input.substring(3,6) + '-' + input.substring(6,10);
    }
    this.setState({phone: input});
}

答案 2 :(得分:1)

要交换和分离样本中的datetime.timestring,可以使用applymapnp.argsort和numpy索引(注意:样本中的数字为字符串格式,因此我检查类型为str

arr = np.argsort(df.applymap(type).ne(str), 1).to_numpy()

Out[985]:
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [2, 3, 0, 1],
       [2, 3, 0, 1]], dtype=int32)

df_out = pd.DataFrame(df.to_numpy()[df.index[:,None], arr], columns=df.columns)

Out[989]:
    a   b         c         d
0   0  10  22:58:00  23:27:00
1  10  17  23:03:00  23:39:00
2   0  10  22:58:00  23:27:00
3  10  17  23:03:00  23:39:00

如果您获得AttributeError: 'DataFrame' object has no attribute 'to_numpy'to_numpy替换为values